Subversion Repositories Kolibri OS

Compare Revisions

No changes between revisions

Regard whitespace Rev 6580 → Rev 6581

/data/Tupfile.lua
138,6 → 138,7
{"kolibrios/3D/info3ds/TL_SYS_16.PNG", PROGS .. "/develop/info3ds/tl_sys_16.png"},
{"kolibrios/3D/info3ds/TOOLBAR.PNG", PROGS .. "/develop/info3ds/toolbar.png"},
{"kolibrios/3D/info3ds/FONT8X9.BMP", PROGS .. "/fs/kfar/trunk/font8x9.bmp"},
{"kolibrios/3D/m2view/", "common/3d/md2view/*"},
{"kolibrios/3D/voxel_editor/VOXEL_EDITOR", PROGS .. "/media/voxel_editor/trunk/voxel_editor"},
{"kolibrios/3D/voxel_editor/CURSORS.PNG", PROGS .. "/media/voxel_editor/trunk/cursors.png"},
{"kolibrios/3D/voxel_editor/CURSORS_GR.PNG", PROGS .. "/media/voxel_editor/trunk/cursors_gr.png"},
194,6 → 195,7
{"kolibrios/games/phenix", PROGS .. "/games/phenix/trunk/phenix"},
{"kolibrios/games/soko/soko", PROGS .. "/games/soko/trunk/SOKO"},
{"kolibrios/games/soko/", "common/games/soko/*"},
{"kolibrios/ggrafx2/", "common/media/grafx2/*"},
{"kolibrios/drivers/ahci/", "common/drivers/ahci/*"},
{"kolibrios/drivers/atikms/", "common/drivers/atikms/*"},
{"kolibrios/drivers/i915/", "common/drivers/i915/*"},
225,7 → 227,7
{"kolibrios/settings/app_plus.ini", "common/settings/app_plus.ini"},
{"kolibrios/utils/appearance", PROGS .. "/cmm/appearance/appearance.com"},
{"kolibrios/utils/calcplus", PROGS .. "/other/calcplus/calcplus"},
{"kolibrios/utils/fNav/", "common/File Managers/fNav*"},
{"kolibrios/utils/fNav/", "common/File Managers/fNav/*"},
}
if build_type == "rus" then tup.append_table(extra_files, {
{"Docs/cp866/config.txt", build_type .. "/docs/CONFIG.TXT"},
/data/common/3d/md2view/md2.cfg
0,0 → 1,15
# ‘¨­â ªá¨á:
# [/path/]file_mod_1.md2 [[/path/]file_text_1.pcx]
# ‚ ª ç¥á⢥ ¯ã⨠¯®¤¤¥à¦¨¢ îâáï ¯®¤ª â «®£¨ ⥪ã饣® ª â «®£  à á¯®«®¦¥­¨ï ¢ìà .
# à¥¤¯®« £ ¥âáï, çâ® ¥á«¨ ¤«ï ä ©«  ⥪áâãàë ­¥ 㪠§ ­
# ¯ãâì â® ®­ à á¯®«®¦¥­ ¢ ⮬ ¦¥ ª â «®£¥ çâ® ¨ ä ©« ¬®¤¥«¨.
# à¥¤¯®« £ ¥âáï â ª ¦¥ çâ®, ¥á«¨ ¤«ï ä ©«  ¬®¤¥«¨ ­¥ 㪠§ ­ ¯ãâì â® ®­ ­ å®¤¨âáï ¢ ⮬ ¦¥
# ª â «®£¥ çâ® ¨ ¢ìà.
 
/md2_model/Ogros.md2 #¬®¤¥«ì ®àª 
md2_model/Weapon.md2 #¬®¤¥«ì ®à㦨ï
 
#md2_model/TRIS.MD2 DRFREAK.PCX
 
#/hd2/1/TEMP/quake_2/QUAKE2/BASEQ2/players/female/tris.md2 athena.pcx
#/hd2/1/TEMP/quake_2/QUAKE2/BASEQ2/players/female/w_disrupt.md2 /athena.pcx
/data/common/3d/md2view/md2View
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/3d/md2view/md2_model/Ogro.txt
0,0 → 1,132
 
 
10/11/98
================================================================
Model Name : Ogro
installation directory : quake2/baseq2/players/ogro
 
Model Author : Magarnigal
email :mellor@netgazer.net.au
homepage :http://magarn.3dpalette.com
 
 
Skins Author : Ogro_Fix
email : ogro_fix@yahoo.com
homepage : http://www.fondation.com/pandemonium
 
Additional info : Fix has included a cloth and ogrobase skin that people may use as a base for skinning ogro. The
mapping can be a bit confusing, 2d skinners beware.
 
 
 
Additional skin by : Deranged - (Sharokh)
email : deranged@deathsdoor.com
homepage : http://www.gibbed.com/thebin
 
 
 
Ogrific law:
 
An Ogro is similar to an ogre, but why the O?? In French ogre is pronounced ogrr, not oger, also 'gros' means to be fat/big...so ogre - gros makes Ogro! After all, it's cuter than just ogre :).
 
The Ogro is smaller than a normal ogre, but just as fat and only slightly less stupid. As opposed to common belief, he is not an evil creature, only killing as is absolutely necessary.
 
Imagine, if you will, an Ogro in the subway. As he enters the carriage, people become plastered to the walls due to Ogro's size. He's too big! Ahh well, maybe Ogro should just sit on one of these tiny seats...a strange sound can be heard (sproottch). Imagine now, the look of an astonished ogro...huh?!? Standing up, he looks at the seat. OMFO! (oh my fucking ogrod!)! Where a little old grandma had been sitting, now looks more like a pizza! But, I swear, it was a grandma!
 
This sort of occurrence is common to an Ogro...its in their nature. when you want to talk to an ogro, stay at good distance (better if you call him from behind), as his movements are rather "uncontrolled", and you might cop a smash in the face!
 
A special diet is required for Ogros. When they're babies (ogrillons), their mum's (ogresses) give them copious amounts of chili con carne, canned beans and the like. The result of this carefully structured diet produces an Ogro capable of immense farting achievements.
 
The ogro is just full of bad smells. That's not to say he's not clean. An ogro will wash himself often (doesn't fear water as opposed to trolls). The problem lies in his intestinal flora (and fauna). all his orifices (ogrifices?) are used for ogrific spells. (green clouds, etc..). Nothing can be done against this kind of onslaught, except to run or stop breathing.
 
It's a useful trait to have in the subway. people will often leave the carriage, trying to find the culprit. (Although all that is need it to look at the face of the ogro: he's
happy, he farted well, and it smells really bad).
 
 
Ogro's existed long before humans. In fact, one school of thought holds to the theory that humans are a degenerated version of Ogro, more intelligent, but evil.
 
 
Hidden Ogro's of today include: Obelix, fat boy slim, any Sumo, Amish (braveheart movie), slamfist (small soldiers movie), bud spencer, etc...
 
 
 
 
Additional Credits to : id software, Howzer, Rod,
 
 
 
================================================================
* Play Information *
 
New Sounds : Yes, original sounds from Eric vonRothkirch of 'The Coven', email him
at redchurch@uswest.net
 
CTF Skins : yes
VWEP Support : yes, standard Id weapons with modified, ogrific skins.
 
 
* Construction *
Poly Counts
Tris.md2 : 670
weapon.md2 : 122
 
Vert Counts
tris.md2 : 358 - anyone actually need this number?
weapon.md2 : 74
 
Skin Wastage
tris.md2 : 1%
weapon.md2 : 2%
 
Skin Count : 14
 
Base : none
 
 
A background to some of the skins:
 
Grok: the standard cyberpunk ogro
 
freedom: this one is dedicated to braveheart.
 
gib: this one didn't know how to use the ogrific mixer (used to make mammoth steaks), and jumped into it..the mixer did all the work.
 
slaanesh: this one is an evil ogro, serving the god of lust.
 
Khorne: this one is even more evil than slaanesh, serving the god of blood and violence.
 
Nabogro: it's a dwarf (yeah, well, it was), he's a trollslayer. In french nabot means small/dwarfy, so, nabogro went logically.
 
darkam: hoo, this one is a troll! (yes, he's green, and ogros hate green), but even if he's green it's the best friend of the original, the true ogro.
 
Igdosh: played with a nuclear missile, thinking it was a cigar...
 
Gorash: he's evil too, has been created by the doctor ogrenstein. but this is the prototype, the real ogrenstein is under construction for now.
 
Arboshak: He felt in love with 3CPO and tried to cyborgize himself. but finally preferred R2D2, but too late
 
 
 
Editors used:-
 
Modelling/animation : Lightwave 5.5
 
Converting/clean-up : QME, Q2modeler
 
Skinning/mapping : NST, Paint shop Pro
 
 
 
Build/Animation time : longer than expected. 5-10 hours per skin.
 
 
* How to use this model *
 
extract to quake2\baseq2\players\ogro run quake2, send us money, frag other players.
 
 
* Copyright / Permissions *
 
QUAKE(R) and QUAKE II(R) are registered trademarks of id Software, Inc.
/data/common/3d/md2view/md2_model/Ogros.md2
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/3d/md2view/md2_model/Weapon.md2
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/3d/md2view/md2_model/Weapon.pcx
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/3d/md2view/md2_model/igdosh.pcx
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/3d/md2view/readme.txt
0,0 → 1,7
md2View v0.01 - Âüþâåð md2 ôàéëîâ ìîäåëåé èãðû Quake2.
Ôàéëû ìîäåëåé è òåêñòóð çàäàþòñÿ â êîíôèãóðàöèîííîì ôàéëå md2.cfg.
Ïîääåðæèâàþòñÿ òåêñòóðû òîëüêî â ôîðìàòå pcx c 8 áèò ãëóáèíîé öâåòà.
 
iadn
http://www.iadn.narod.ru
iadn@bk.ru
/data/common/media/grafx2/fonts/5pxtinyfont.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/fonts/8pxfont.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/fonts/GrafX2_Black.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/fonts/GrafX2_Dark.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/fonts/PF_Arma_5__.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/fonts/PF_Easta_7_.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/fonts/PF_Easta_7__.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/fonts/PF_Ronda_7__.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/fonts/PF_Tempesta_5.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/fonts/PF_Tempesta_5_.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/fonts/PF_Tempesta_5__.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/fonts/PF_Tempesta_5___.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/fonts/PF_Tempesta_7.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/fonts/PF_Tempesta_7_.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/fonts/PF_Tempesta_7__.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/fonts/PF_Tempesta_7___.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/fonts/PF_Westa_7_.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/fonts/PF_Westa_7__.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/fonts/Tuffy.ttf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/fonts/colorfont.pcx
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/gfx2.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/gfx2.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/gfx2def.ini
0,0 → 1,420
###### GrafX2 initialization file ###### Fichier d'initialisation de GrafX2 ##
# # # #
# You may modify this file with any # Vous pouvez modifier ce fichier avec #
# standard ASCII text editor. # n'importe quel éditeur de texte #
# # ASCII standard. #
# # #
# Comments are preceded by ';' or # Les commentaires sont précédés par #
# '#'. # ';' ou '#'. #
# # #
# Options are not case sensitive and # Les options ne sont pas sensibles à #
# spaces are ignored. # la casse et les espaces sont ignorés.#
# # #
# You must not change the order of # Vous ne devez pas changer l'ordre #
# the sections and their options. # des sections et de leurs options. #
# You must not delete or put into # Vous ne devez pas effacer ou mettre #
# comment any section nor option. # en commentaire une section ou option.#
# # #
# Each option is preceded by a # Chaque option est précédée par un #
# comment which explains its meaning. # commentaire qui explique sa fonction.#
# # #
##############################################################################
 
 
 
[MOUSE] # [SOURIS]
 
; The sensitivity of the mouse can | La sensibilité de la souris peut
; take values from 1 to 4. The | prendre des valeurs de 1 à 4. Plus
; smaller values, the faster. | les valeurs sont petites, plus c'est
; This only takes effect in | rapide. Ce paramétrage n'est utilisé
; fullscreen modes. | que dans les modes "plein écran".
; |
X_sensitivity = 1 ; (default 1)
Y_sensitivity = 1 ; (default 1)
 
; Unused setting, only kept for compatibility.
X_correction_factor = 0 ; (default 0)
Y_correction_factor = 0 ; (default 0)
 
; Aspect of the main cursor (cross) | Aspect du curseur principal (croix)
; 1: Solid | 1: Solide
; 2: Transparent | 2: Transparent
; 3: Thin (solid) | 3: Fin (solide)
Cursor_aspect = 1 ; (default 1)
 
[MENU] # [MENU]
 
; Colors of the menus (the black | Couleurs des menus (la couleur noire
; and the white colors cannot be | et la couleur blanche ne peuvent pas
; modified). | être modifiées).
; Values are in {Red,Green,Blue} | Les valeurs sont dans l'ordre {Rouge,
; order and are between 0 and 63. | Vert,Bleu} et vont de 0 à 63.
Light_color = 42,42,42 ; (default 42,42,42)
Dark_color = 27,27,27 ; (default 27,27,27)
;
; Light_color = 24,25,30 ; \_ Nightmare
; Dark_color = 13,14,19 ; /
;
; Light_color = 10,45,28 ; \_ Forest
; Dark_color = 5,27,12 ; /
;
; Light_color = 48,41,26 ; \_ Gold
; Dark_color = 26,22,15 ; /
;
; Light_color = 10,40,55 ; \_ Oceanic
; Dark_color = 10,20,32 ; /
 
; Aspect ratio and size of the | Proportion des menus et de la barre
; menus and the tool-bar. | d'outils.
; Possible values: | Valeurs possibles:
; 0: Do not adapt (pixels are not | 0: Ne pas adapter (les pixels ne sont
; stretched) | pas étirés)
; 1: Adapt the menus and the tool- | 1: Adapter les menus et la barre
; bar according to the resolution| d'outils suivant la résolution
; 2: Slightly adapt the ratio of | 2: Adapter légèrement les proportions
; the menus and tool-bar | des menus et de la barre d'outils
; -1:Do not adapt (like 0) | -1:Ne pas adapter (comme 0)
; -2:Stretch by x2 maximum | -2:Etire au double de taille si possible
; -3:Stretch by x3 maximum | -3:Etire au triple de taille si possible
; -4:Stretch by x4 maximum | -3:Etire au quadruple de taille si
; | possible.
Menu_ratio = -2 ; (default -2)
 
[FILE_SELECTOR] # [SELECTEUR_DE_FICHIERS]
 
; Show hidden files and | Afficher les fichiers et répertoires
; directories (values are 'yes' or | cachés (les valeurs sont 'yes' ou
; 'no'). | 'no').
Show_hidden_files = no ; (default 'no')
Show_hidden_directories = no ; (default 'no')
 
; Delay before displaying a preview | Délai avant d'afficher une preview
; in file-selectors (in 18.2th of | dans les sélecteurs de fichiers (en
; second). Possible values range | 18.2èmes de seconde) Les valeurs
; from 1 to 256. | possibles vont de 1 à 256.
Preview_delay = 8 ; (default 8)
 
; Maximize the preview of the | Maximiser la preview des images pour
; pictures so that it is as big as | qu'elle soit aussi grande que
; possible. If you're not in the | possible.
; same resolution as the picture's | Si vous n'êtes pas dans la même réso-
; one, it can try to correct the | lution que celle de l'image, cela peut
; aspect ratio, but if the picture | essayer de corriger les proportions,
; does not fill the whole screen, | mais si l'image ne prend pas tout
; it can be worse. | l'écran, cela peut être pire.
Maximize_preview = no ; (default 'no')
 
; This option is used to place the | Cette option est utilisée pour placer
; selection bar on a filename by | la barre de sélection sur un nom de
; typing its first letters. | fichier en tapant ses 1ères lettres.
; For example, if you want to find | Par exemple, si vous voulez trouver le
; the "PICTURE.PKM" in a directory | fichier "PICTURE.PKM" dans un réper-
; that also contains "PALETTE.PAL", | toire contenant également le fichier
; you'll just have to type P and I. | "PALETTE.PAL", vous n'aurez qu'à taper
; The different values of "FFF" | P puis I.
; indicate if you want to find the | Les different valeurs de "FFF"
; name in both files and directories| indiquent si vous voulez trouvez le nom
; or just in only one of these: | dans les fichiers ET les répertoires ou
; 0: files and directories | simplement dans l'un OU l'autre.
; 1: files only | 0: fichiers et répertoires
; 2: directories only | 1: fichiers seulement
; | 2: répertoires seulement
Find_file_fast = 0 ; (default 0)
 
 
[LOADING] # [CHARGEMENT]
 
; Automatically set the resolution | Passer automatiquement dans la bonne
; when loading a picture. | résolution lors du chargement d'une
; You should set this value to | image.
; 'yes' after disabling the video | Vous devriez définir cette option à
; modes that are not supported by | 'yes' après avoir inhibé les modes
; your video card or monitor. | vidéo qui ne sont pas supportés par
; | votre matériel.
Auto_set_resolution = no ; (default 'no')
 
; If the variable above is set to | Si la variable ci-dessus est à 'yes',
; 'yes', this one tells if you want | celle-ci indique si vous voulez
; to set the resolution according | définir la résolution suivant:
; to: | 1: les dimensions de "l'écran
; 1: the internal "original screen" | d'origine" internes à l'image
; dimensions of the picture | 2: les véritables dimensions de
; 2: the actual dimensions of the | l'image
; picture |
Set_resolution_according_to = 1 ; (default 1)
 
; If you load a picture with a | Si vous chargez une image ayant une
; palette of less than 256 colors, | palette de moins de 256 couleurs,
; this option defines if you want | cette option indique si vous souhaitez
; to clear the palette or to keep | effacer la palette ou bien conserver
; the colors of the previous | les couleurs de l'image précédente qui
; picture that are over the number | se situent au-delà du nombre de la
; of colors of the new picture. | nouvelle image.
; For example, if you load a | Par exemple, si vous chargez une image
; 32-color picture, the colors 32 | de 32 couleurs, les couleurs 32 à 255
; to 255 will be set to black if | seront passées en noir si cette option
; this option is set to 'yes', or | est à 'yes', ou bien elles resteront
; they will be kept unchanged if | inchangées si elle est à 'no'.
; this option is set to 'no'. |
Clear_palette = yes ; (default 'yes')
 
 
[MISCELLANEOUS] # [DIVERS]
 
; Draw the limits of the picture. | Afficher les limites de l'image
Draw_limits = yes ; (default 'yes')
 
; Adjust the brush grabbing in | Ajuster la capture de brosse en mode
; "grid" mode. | "grille".
Adjust_brush_pick = yes ; (default 'yes')
 
; Coordinates: | Coordonnées:
; 1: Relative | 1: Relatives
; 2: Absolute | 2: Absolues
Coordinates = 1 ; (default 1)
 
; Create a backup file when saving. | Créer un fichier backup lors des
; | sauvegardes.
Backup = no ; (default 'no')
 
; Number of pages stored in memory | Nombre de pages stockées en mémoire
; for "undoing". | destinées à annuler les dernières
; Values are between 1 and 99. | modifications. Valeurs entre 1 et 99.
Undo_pages = 20 ; (default 20)
 
; Speed of the scroll-bars (in VBLs | Vitesse des barre de défilement (en
; waited) while clicking with the | VBLs attendus) lorsque l'un des
; left or right button of the mouse.| boutons de la souris est enfoncé.
; Values can be between 1 and 255. | Les valeurs sont comprises entre 1 et
; The bigger values, the slower. | 255. Plus elles sont grandes, plus
; | c'est lent.
Gauges_scrolling_speed_Left = 10 ; (default 10)
Gauges_scrolling_speed_Right = 3 ; (default 3)
 
; Automatically save the configu- | Enregistre automatiquement la configu-
; ration when exiting the program. | ration lorsqu'on quitte le programme.
Auto_save = yes ; (default 'yes')
 
; Maximum number of vertices used | Nombre maximum de vertex utilisés dans
; in filled polygons and polyforms, | les polygônes et polyformes pleins, et
; and lasso. Possible values range | le lasso. Les valeurs possibles vont
; from 2 to 16384. | de 2 à 16384.
; Each vertex takes 4 bytes. | Chaque vertex prend 4 octets.
Vertices_per_polygon = 1024 ; (default 1024)
 
; Automatically zoom into the | Zoomer automatiquement la zone pointée
; pointed area when you press the | par la souris lorsque vous appuyez sur
; short-key of the Magnifier button | la touche de raccourci de la loupe.
; while being above the picture. |
Fast_zoom = yes ; (default 'yes')
 
; Separate the colors in the tool- | Séparer les couleurs dans la barre
; bar by a black squaring. | d'outils par un quadrillage noir.
Separate_colors = no ; (default 'no')
 
; Initial value of the feedback for | Valeur initiale du "feedback" pour les
; the drawing modes (cf. docs). | modes de dessin (cf. docs).
FX_feedback = yes ; (default 'yes')
 
; When you reduce the palette or | Si vous réduisez la palette ou "zappez"
; "zap" some colors out of it, it is| quelques couleurs, il est possible
; possible that there are not enough| qu'il ne reste pas assez de couleurs
; colors left to draw the menus. | pour afficher les menus. Mettre cette
; Switching the following variable | variable à 'yes' ramènera automatiquent
; on will bring back the colors of | les couleurs du menu s'il reste moins
; the menu if there are less than 4 | de 4 couleurs après une "réduction" ou
; colors left after "reducing" or | un "zapping".
; "zapping". |
Safety_colors = yes ; (default 'yes')
 
; Display a message at startup | Afficher un message au démarrage
; telling the version number of the | indiquant le numéro de version du
; program. | programme.
Opening_message = yes ; (default 'yes')
 
; Take the Stencil into account when| Prendre le Stencil en compte lorsqu'on
; clearing the image. | efface l'image.
Clear_with_stencil = yes ; (default 'yes')
 
; Directly set the discontinuous | Passer automatiquement en mode de
; freehand drawing mode after brush | dessin discontinu après la prise d'une
; grabbing. | brosse.
Auto_discontinuous = no ; (default 'no')
 
; Save the screen dimensions in GIF | Sauver les dimensions de l'écran dans
; files. If you want to read these | les fichiers GIF. Si vous voulez lire
; files with Photoshop or Alchemy, | ces fichiers avec Photoshop ou Alchemy,
; and maybe some other programs, you| et peut-être d'autres programmes, vous
; must set this option to 'no'. | devez mettre cette option à 'no'.
Save_screen_size_in_GIF = no ; (default 'no')
 
; Automaticaly count the number of | Compter automatiquement le nombre de
; different colors used when opening| couleurs différentes utilisées lors de
; the palette editor window. (Set it| d'ouverture de la fenêtre d'édition de
; to 'no' if you have a slow PC or | la palette. (Mettez-le à 'no' si vous
; if you edit huge pictures) | avez un PC lent ou bien si vous éditez
; | d'énormes images).
Auto_nb_colors_used = yes ; (default 'yes')
 
; Default video mode at startup | Mode vidéo par défaut au
; (see the list by running the | démarrage (voir la liste en lançant
; program with argument "/?". | le programme avec l'option "/?".
Default_video_mode = window ; (default 'window')
 
; Window dimensions. The program | Dimensions de la fenêtre en mode
; remembers the last window size. | fenêtré.
Default_window_size = 640,480 ; (default '640,480')
 
; This setting allows you merge successive mouse movements into a single
; mouse movement. You should only use it if you are using a mouse which
; reports at 200Hz or more, and you experience lag when using discontinuous
; hand-drawing with large brushes (this tool tries to paste the brush and
; update the screen on each new mouse position) In this case, set this to 2
; or more, to ignore some intermediate mouse reports when a more recent one
; is present.
; Note that with a value superior to 1, you lose precision with continuous
; hand-drawing, as intermediate mouse positions are skipped.
Merge_movement = 0 ; (default 0)
 
; Number of columns in the palette of the menu bar. Can be any number from
; 1 to 256. If there is not enough room, the program will display less
; columns. But your preference will be kept, and as soon as there is more
; space in the screen, more columns will be shown.
;
Palette_Cells_X = 16; (Default 16)
; Number of lines in the palette of the menu. Can be any number from
; 1 to 16. The menu can always display the number of lines you request.
;
Palette_Cells_Y = 4; (Default 4)
 
; Bookmarked directories. Leave the directory blank for unused ones.
;
Bookmark_label =
Bookmark_directory =
 
Bookmark_label =
Bookmark_directory =
 
Bookmark_label =
Bookmark_directory =
 
Bookmark_label =
Bookmark_directory =
 
; In the classic layout, the palette in the menu has colors from left to
; right. If you prefer the colors ordered top to bottom, set this option
; to YES.
;
Palette_vertical = YES; (Default YES)
 
; The program remembers the last window position, if the
; OS isn't able to do it by itself. (ie: Windows)
Window_position = 9999,9999; (Default 9999,9999 which means: NA)
 
; This is the time (in milliseconds) between two clicks for Grafx2 to
; recognize a double-click. Double-click is used mostly in the palette
; area of the menu: double-click a color to open the palette.
Double_click_speed = 500; (Default 500)
 
; When you press two digit keys in rapid succession (ex: 3 8), Grafx2
; sets transparency to 38% (instead of 30% then 80%). This setting
; allows you to set the maximum delay between two keypresses for
; GrafX2 to recognize them as a combo.
Double_key_speed = 500; (Default 500)
 
; Name of the skinfile you want to | Nom du fichier skin que vous voulez
; use. | utiliser.
; Default : (empty to let the program choose)
Skin_file =
 
; Name of the font file (8x8) you | Nom du fichier police de caractère
; want to use. | 8x8 utilisée dans les menus.
; Default : (empty to let the program choose)
Font_file =
 
; This determines the color value for the grid. Each pixel of
; the grid will be displayed by XOR-ing the original color with
; the value of this setting.
; For example, if you always paint 16-color images, you can set it
; to 16 so the color of the grid are 16 for 0, 17 for 1, etc.
; Then you can set colors 16-31 as lighter/darker variants
; of your original palette, resulting in a pretty grid !
;
; Valid values are 1 to 255.
Grid_XOR_color = 255; (Default 255)
 
; This records the last pixel ratio used, to restore it on start.
; Valid values are from 0 to 7 for: Simple, Wide, Tall, Double,
; Triple, Wide2, Tall2, Quadruple.
;
Pixel_ratio = 0; (Default 0)
 
; This records the visibility of toolbars, to restore them on start.
; It's a bitfield, where 1=Status, 2=Layers/Animation, 4=Tools
;
Menubars_visible = 255; (Default 255)
; This enables a mode where right mouse buttons acts as
; a color picker, with most tools.
;
Right_click_colorpick = NO; (Default NO)
 
; When this mode is active, scrolling the view (and the magnifier view)
; affects both the main image and the spare page - as long as they have
; the same dimensions.
;
Sync_views = YES; (Default YES)
; This setting determines which key inverts the mouse buttons
; when it's held : A left click is then interpreted as a right-click.
; It's especially useful for one-button controllers,
; such as touchscreens and tablets.
; Possible values are 0 (none), 1 (control), 2 (alt)
;
Swap_buttons = 1; (Default 1)
; Last directory browsed with the script selector.
; Leave blank to initially start in (data directory)/scripts
;
Scripts_directory =
; When this setting is disabled, and you create a shortcut with a key that
; is already associated to another shortcut, Grafx2 will unset the latter.
; If you enable this mode, Grafx2 will not make such check, so you can design
; shortcuts that trigger several actions at once.
;
Allow_multi_shortcuts = no; (Default no)
; Determines if the Tilemap tool should identify tiles that are mirrored
; version of other tiles, on the X axis.
;
Tilemap_detect_mirrored_x = no; (Default no)
 
; Determines if the Tilemap tool should identify tiles that are mirrored
; version of other tiles, on the Y axis.
;
Tilemap_detect_mirrored_y = no; (Default no)
; Determines if the Tilemap tool should identify tiles that are reversed
; versions of other tiles (180°).
;
Tilemap_detect_mirrored_xy = no; (Default no)
 
; Determines if the Tilemap tool should show the number of distinct tiles
; at the end of analysis.
;
Tilemap_count = no; (Default no)
 
; Enables the virtual keyboard when the user enters a textbox.
;
; 0=Auto (guess), 1=ON, 2=OFF
Use_virtual_keyboard = 0; (Default 0)
; Indicates if new images should by default use layers. The alternative
; is animation frames.
;
Default_mode_layers = no; (Default no)
; end of configuration
/data/common/media/grafx2/grafx2
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/scripts/_tst_AAFilter.lua
0,0 → 1,30
-- Apply a kind of AA filter on picture
 
-- Get the picture size
w, h = getpicturesize();
 
-- Here is the filtering matrix
matrix = {
{ 0, -1, 0 },
{ -1, 5, -1 },
{ 0, -1, 0 }};
 
-- Loop trough all the pixels
-- To make this script simpler we don't handle the picture borders
-- (the matrix would get pixels outside the picture space)
-- for var = start_value, end_value, step do ...
for y = 1, h - 2, 1 do
for x = 1, w - 2, 1 do
filtered =
matrix[1][1] * getbackuppixel(x - 1, y - 1) +
matrix[1][2] * getbackuppixel(x , y - 1) +
matrix[1][3] * getbackuppixel(x + 1, y - 1) +
matrix[2][1] * getbackuppixel(x - 1, y ) +
matrix[2][2] * getbackuppixel(x , y ) +
matrix[2][3] * getbackuppixel(x + 1, y ) +
matrix[3][1] * getbackuppixel(x - 1, y + 1) +
matrix[3][2] * getbackuppixel(x , y + 1) +
matrix[3][3] * getbackuppixel(x + 1, y + 1);
putpicturepixel(x,y,filtered);
end
end
/data/common/media/grafx2/scripts/_tst_GradientBrush.lua
0,0 → 1,7
w, h = getbrushsize()
 
for x = 0, w - 1, 1 do
for y = 0, h - 1, 1 do
putbrushpixel(x, y, (x+y)%256);
end
end
/data/common/media/grafx2/scripts/_tst_Settings.lua
0,0 → 1,33
-- Test LUA inputbox
-- this script tests the inputbox
 
w, h = getbrushsize()
--[[
messagebox(
"Forecolor: " .. getforecolor() .. "\n" ..
"Backcolor: " .. getbackcolor() .. "\n" ..
"Transparent color: " .. gettranscolor() .. "\n" ..
"Brush dimensions: " .. w .. "x" .. h
)
]]
 
 
ok, w, h = inputbox("Modify brush",
"RGB", 1, 0, 1, -1,
"HSV", 0, 0, 1, -1,
"HSL", 0, 0, 1, -1,
"Width", w, -900.0,900.0, 3,
"Height", h, -900.0,900.0, 4,
"X Flip", 0, 0, 1, 0,
"Y Flip", 0, 0, 1, 0,
"Degrees",1, 0, 1, -2,
"Radians",0, 0, 1, -2
);
if ok == true then
messagebox(
"w: " .. w .. "\n" ..
"h: " .. h .. "\n"
)
end
 
 
/data/common/media/grafx2/scripts/_tst_dialog.lua
0,0 → 1,66
local counter=0;
local printcounter = function ()
windowprint(10,54, string.format("% .3d", counter));
end;
 
windowopen(100,150, "Dialogtest");
windowbutton(6, 18, 54, 14, "Close", 27); -- 1, shortcut=ESC
windowrepeatbutton(6, 38, 14, 14, "+"); -- 2
windowrepeatbutton(26, 38, 14, 14, "-"); -- 3
windowbutton(6, 70, 54, 14, "Help"); -- 4
windowinput(6, 88, 10);
printcounter();
 
repeat
local button, button2, key = windowdodialog();
 
if button == 2 then -- "+"
counter=counter+1;
printcounter();
end
if button == 3 then -- "-"
counter=counter-1;
printcounter();
end
if button == 4 then -- "Help"
messagebox("Help screen");
end
until key == 27 or button == 1;
windowclose();
 
 
-- messagebox(tostring(button) .. " " .. tostring(button2));
 
 
---- Open_window(149,118,"Grid");
-- Display_cursor();
-- Hide_cursor();
---- Close_window();
---- Update_window_area(0,0,Window_width, Window_height);
---- clicked_button=Window_clicked_button();
--
-- -- standard button
---- Window_set_normal_button(12,92,51,14,"Cancel",0,1,KEY_ESC); -- 1
-- -- repeatable button (while held)
---- Window_set_repeatable_button(202,43,13,11,"-",0,1,SDLK_LAST); -- 8
-- -- text input
-- Window_set_input_button(29,24,3); -- 3
-- Window_input_content(input_x_button,str);
-- Readline(31,26,str,3,INPUT_TYPE_INTEGER);
--
-- -- dropdown
-- Window_set_dropdown_button(216, 158, 84,14,84,"Preset...", 0,0,1,RIGHT_SIDE|LEFT_SIDE,1);
-- Window_dropdown_clear_items(Button);
-- Window_dropdown_add_item(Button,0,"Set");
--
-- -- vertical scroller
-- mix_scroller = Window_set_scroller_button(31,20,84,256,1,Main_backups->Pages->Gradients->Range[Current_gradient].Mix);
-- Window_draw_slider(mix_scroller);
--
-- -- display
---- Print_in_window(11,26, "X:",MC_Dark,MC_Light);
---- Print_in_window_limited(Button->Pos_X+3+10,Button->Pos_Y+2,Config.Bookmark_label[bookmark_number],8,MC_Black,MC_Light);
-- Window_display_frame_in( 6, 21,110, 52);
-- Window_display_frame(6,17,130,37);
-- Window_rectangle(panel->Pos_X, panel->Pos_Y, panel->Width, panel->Height+1, MC_Light);
 
/data/common/media/grafx2/scripts/_tst_dialog2.lua
0,0 → 1,33
--
-- test of GUI library
--
run("libs/gui.lua")
 
local counter = gui.label{x=10, y=54, value=0, format="% .3d"}
local form = gui.dialog{
title="Dialogtest",
w=100,
h=150,
counter,
gui.button{ label="+",
x=6, y=38, w=14, h=14, repeatable=true, click=function()
counter.value=counter.value+1;
counter:render();
end},
gui.button{ label="-",
x=26, y=38, w=14, h=14, repeatable=true, click=function()
counter.value=counter.value-1;
counter:render();
end},
gui.button{ label="Help",
x=6, y=70, w=54, h=14, click=function()
messagebox("Help screen");
end},
gui.button{ label="Close",
x=6, y=18, w=54, h=14, key=27, click=function()
return true; -- causes closing
end},
}
 
form:run()
 
/data/common/media/grafx2/scripts/libs/gui.lua
0,0 → 1,111
--
-- Event-driven GUI library
--
--
 
gui = {
 
--
-- dialog() --
--
dialog = function(args)
local dia = {
title = args.title,
w = args.w,
h = args.h,
--
widgets = {},
-- an indexed array, starting at 1. Used for calling the relevant
-- callback when a numbered control is clicked.
callbacks = {},
--
-- dialog.run() --
--
run = function(this)
windowopen(this.w,this.h, this.title or "");
-- examine all elements
for _,widget in ipairs(this.widgets) do
widget:render()
end
repeat
local button, button2, key = windowdodialog();
if button > 0 then
local c = this.callbacks[button]
-- run the callback and stop the form if it returns true
if c ~= nil and c(this) then
break;
end
end
until key == 27;
windowclose();
end
}
local id = 1;
-- examine all elements
for _,value in ipairs(args) do
-- all arguments that are tables are assumed to be widgets
if type(value)=="table" then
table.insert(dia.widgets, value)
-- clickable widgets take up an auto-numbered id
if (value.click) then
dia.callbacks[id] = value.click
id=id+1
end
end
end
return dia;
end,
 
--
-- button() --
--
button = function(args)
local but = {
x = args.x,
y = args.y,
w = args.w,
h = args.h,
key = args.key,
label = args.label,
click = args.click or donothing,
render = args.repeatable and function(this)
windowrepeatbutton(this.x, this.y, this.w, this.h, this.label, this.key or -1);
end
or function(this)
windowbutton(this.x, this.y, this.w, this.h, this.label, this.key or -1);
end
}
return but;
end,
 
--
-- label() --
--
label = function(args)
local fld = {
x = args.x,
y = args.y,
value = args.value,
format = args.format,
fg = args.fg or 0,
bg = args.bg or 2,
render = function(this)
if type(this.format) then
windowprint(this.x, this.y, string.format(this.format, this.value), this.fg, this.bg);
else
windowprint(this.x, this.y, this.value, this.fg, this.bg);
end
end
}
return fld;
end,
 
 
-- "do nothing" function. Used as default callback
donothing = function(this)
end
 
}
/data/common/media/grafx2/scripts/samples_2.4/brush/ApplyColor.lua
0,0 → 1,129
--BRUSH Remap: Apply PenColor
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
 
-- Copyright 2010 Richard Fhager
--
-- 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; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
run("../libs/dawnbringer_lib.lua")
 
OK,tin,clz,fade,amt,brikeep,falloff,nobg,nopen,briweight = inputbox("Apply PenColor 2 Brush",
"1. Tint", 1, 0,1,-1,
"2. Colorize", 0, 0,1,-1,
"BG->FG color Fade", 0, 0,1,0,
"AMOUNT % (0-100)", 100, 0,100,0,
"Preserve Brightness", 1, 0,1,0,
"Bri/Dark FallOff", 1, 0,1,0,
"Exclude Background", 1,0,1,0,
"Exclude PenColor", 0,0,1,0,
"ColMatch Bri-Weight %", 25, 0,100,0
);
 
 
if OK == true then
 
function cap(v) return math.min(255,math.max(v,0)); end
 
w, h = getbrushsize()
 
 
fg = getforecolor()
bg = getbackcolor()
fR,fG,fB = getcolor(fg)
bR,bG,bB = getcolor(bg)
 
pal = db.fixPalette(db.makePalList(256))
if nobg == 1 then
pal = db.stripIndexFromPalList(pal,bg) -- Remove background color from pallist
end
if nopen == 1 then
pal = db.stripIndexFromPalList(pal,fg) -- Remove Pencolor from pallist
end
 
 
amtA = amt / 100
amtR = 1 - amtA
 
-- Normalize Pen Color
lev = (fR+fG+fB)/3
fR = fR - lev
fG = fG - lev
fB = fB - lev
 
---------------------------------------------------
-- Colorize (Colourant) (just apply colorbalance)
-- Tint (make grayscale and apply colorbalance)
--
-- I think it should be the other way around since colorize is the process of adding color to B&W film...
-- But this is the what Brilliance and others call it
--
if clz == 1 or tin == 1 then
cols = {}
for n = 0, 255, 1 do
 
r,g,b = getcolor(n)
a = db.getBrightness(r,g,b)
 
mR,mG,mB = fR,fG,fB
 
-- Fade between bg & fg pencolor across dark-bright
if fade == 1 then
lf = a / 255
lr = 1 - lf
mR = bR*lr + fR*lf
mG = bG*lr + fG*lf
mB = bB*lr + fB*lf
lev = (mR+mG+mB)/3
mR = mR - lev
mG = mG - lev
mB = mB - lev
end
 
fr,fg,fb = mR,mG,mB
 
if brikeep == 1 then
-- Loose Brightness preservation (ex: applying full red to dark colors)
brin = db.getBrightness(cap(r+mR),cap(g+mG),cap(b+mB))
itot = brin - a
fr = mR - itot
fg = mG - itot
fb = mB - itot
end
 
-- Falloff (Effect weakens at dark and bright colors)
if falloff == 1 then
fo = 1 - math.abs((a - 127.5)/127.5)^2
fr = fr * fo
fg = fg * fo
fb = fb * fo
end
 
if tin == 1 then
--cols[n+1] = matchcolor((a+fr)*amtA + r*amtR, (a+fg)*amtA + g*amtR, (a+fb)*amtA + b*amtR)
cols[n+1] = db.getBestPalMatchHYBRID({(a+fr)*amtA+r*amtR, (a+fg)*amtA + g*amtR, (a+fb)*amtA + b*amtR},pal,briweight / 100,true)
end
if clz == 1 then
--cols[n+1] = matchcolor((r+fr)*amtA + r*amtR, (g+fg)*amtA + g*amtR, (b+fb)*amtA + b*amtR)
cols[n+1] = db.getBestPalMatchHYBRID({(r+fr)*amtA+r*amtR, (g+fg)*amtA + g*amtR, (b+fb)*amtA + b*amtR},pal,briweight / 100,true)
end
end
 
if nobg == 1 then cols[getbackcolor()+1] = getbackcolor(); end
 
for x = 0, w - 1, 1 do
for y = 0, h - 1, 1 do
putbrushpixel(x, y, cols[getbrushpixel(x,y) + 1]);
end
end
end;
-- eof Colorize & Tint
--------------------------------------------------------
 
end -- OK
/data/common/media/grafx2/scripts/samples_2.4/brush/Fisheye.lua
0,0 → 1,31
--BRUSH Distortion: FishEye
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
 
-- Copyright 2010 Richard Fhager
--
-- 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; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
-- This script was adopted from Evalion, a Javascript codecrafting/imageprocessing project
--http://goto.glocalnet.net/richard_fhager/evalion/evalion.html
 
w, h = getbrushsize()
 
 
for y = 0, h - 1, 1 do
for x = 0, w - 1, 1 do
 
ox = x / w;
oy = y / h;
v = (math.cos((ox-0.5)*math.pi)*math.cos((oy-0.5)*math.pi))*0.85;
ox = (1 + ox - (ox-0.5)*v) % 1;
oy = (1 + oy - (oy-0.5)*v) % 1;
c = getbrushbackuppixel(math.floor(ox*w),math.floor(oy*h));
putbrushpixel(x, y, c);
end
end
 
/data/common/media/grafx2/scripts/samples_2.4/brush/GrayscaleAvg.lua
0,0 → 1,24
--BRUSH Remap: Grayscale (average)
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
 
-- Copyright 2010 Richard Fhager
--
-- 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; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
w, h = getbrushsize()
 
for x = 0, w - 1, 1 do
for y = 0, h - 1, 1 do
r, g, b = getcolor(getbrushpixel(x,y))
 
a = (r+g+b)/3
 
putbrushpixel(x, y, matchcolor(a,a,a));
 
end
end
/data/common/media/grafx2/scripts/samples_2.4/brush/GrayscaleDesat.lua
0,0 → 1,36
--BRUSH Remap: Grayscale (desaturate)
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
 
-- Copyright 2010 Richard Fhager
--
-- 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; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
-- This script was adopted from Evalion, a Javascript codecrafting/imageprocessing project
--http://goto.glocalnet.net/richard_fhager/evalion/evalion.html
 
 
percent = 100
 
--
function desaturate(percent,r,g,b) -- V1.0 by Richard Fhager
p = percent / 100
a = (math.min(math.max(r,g,b),255) + math.max(math.min(r,g,b),0)) * 0.5 * p
r = r + (a-r*p)
g = g + (a-g*p)
b = b + (a-b*p)
return r,g,b
end
--
 
 
w, h = getbrushsize()
 
for x = 0, w - 1, 1 do
for y = 0, h - 1, 1 do
putbrushpixel(x, y, matchcolor(desaturate(percent,getcolor(getbrushpixel(x,y)))));
end
end
/data/common/media/grafx2/scripts/samples_2.4/brush/Halfsmooth.lua
0,0 → 1,34
--BRUSH: Halfsize with smoothscaling
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
 
-- Copyright 2010 Richard Fhager
--
-- 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; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
w, h = getbrushsize()
 
setbrushsize(math.floor(w/2),math.floor(h/2))
 
for x = 0, w - 1, 2 do
for y = 0, h - 1, 2 do
r1,g1,b1 = getcolor(getbrushbackuppixel(x,y));
r2,g2,b2 = getcolor(getbrushbackuppixel(x+1,y));
r3,g3,b3 = getcolor(getbrushbackuppixel(x,y+1));
r4,g4,b4 = getcolor(getbrushbackuppixel(x+1,y+1));
r = (r1 + r2 + r3 + r4 ) / 4;
g = (g1 + g2 + g3 + g4 ) / 4;
b = (b1 + b2 + b3 + b4 ) / 4;
c = matchcolor(r,g,b);
 
putbrushpixel(x/2, y/2, c);
 
end
end
 
 
/data/common/media/grafx2/scripts/samples_2.4/brush/Waves.lua
0,0 → 1,42
--BRUSH Distortion: Waves v1.0
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
 
-- Copyright 2010 Richard Fhager
--
-- 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; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
-- This script was adopted from Evalion, a Javascript codecrafting/imageprocessing project
-- http://goto.glocalnet.net/richard_fhager/evalion/evalion.html
 
 
--frq = 2
--amp = 0.3
 
-- Adjust power of frequency & amplitude
frq_adj = 2
amp_adj = 0.02
 
ok,frq,amp = inputbox("Settings",
"Frequency 1-10", 3, 1,10,0,
"Amplitude 1-10", 3, 1,10,0
);
 
w, h = getbrushsize()
 
for y = 0, h - 1, 1 do
for x = 0, w - 1, 1 do
 
ox = x / w;
oy = y / h;
ox = (1 + ox + math.sin(oy*math.pi*frq*frq_adj)*amp*amp_adj) % 1;
c = getbrushbackuppixel(math.floor(ox*w),y);
putbrushpixel(x, y, c);
 
end
end
 
/data/common/media/grafx2/scripts/samples_2.4/codenetsend.lua
0,0 → 1,17
-- Codenet send for grafx2 2.4 and up, by Michael Ilsaas.
-- Sends the latest saved picture. Set the IP address of the C64 in the line below.
ip = "192.168.0.64"; -- <-- IP address of the C64.
fn, fp = getfilename();
picfile = assert(io.open(fp .. '/' .. fn ,"r"));
picsize = picfile:seek("end")
picfile:close();
if picsize == 9000 or picsize == 9002 then -- check for hires
os.execute("echo AQgLCAoAnjIwNjIAAAAArQDdKfwJAo0A3ak4jRjQqQiNFtCpO40R0KkAjSDQogC9DA6dAGC9DA+dAGG9DBCdAGK9DBGdAGO9DBKdAGS9DBOdAGW9DBSdAGa9DBWdAGe9DBadAGi9DBedAGm9DBidAGq9DBmdAGu9DBqdAGy9DBudAG29DBydAG69DB2dAG/o4ADQm6IAvQwenQBwvQwfnQBxvQwgnQByvQwhnQBzvQwinQB0vQwjnQB1vQwknQB2vQwlnQB3vQwmnQB4vQwnnQB5vQwonQB6vQwpnQB7vQwqnQB8vQwrnQB9vQwsnQB+vQwtnQB/6OAA0JuiAL1MLZ0ATL1MLp0ATb1ML50ATr1MMJ0AT+jgANDjvUUJnQDAvUUKnQDBvUULnQDCvUUMnQDDvUUNnQDEvUUOnQDF6OAA0NdMAMCpwI00A6mojTUDqQCNNgOpQI03A60B3gkBjQHeor+gxCBbwxAJqQagwqkITLnESKkYoMJoqQ14IP7DEPtYIOH/0ANMucR4IP7DMPGtRAPJCNDqrUUD8ArJBtDhIA/DTDzArUYDyUXQ1K1MAym/DU0D0MqtTwPJEfA2yQHwCKkCIKzCTDzArVoDyQjQIKkAjVoDGK1cA2kIjVwDkAruXQPQBe5cA/D2IDjCIJnCTDzArVwDyRnQB61dA8k+8AipAyCswkw8wK1iA8nK0OCtYwPJH9DZrWUDSKkBjWUDqQCNSAONXgONYAOF+oX7qSCNSQOpGI1fA6kRjWEDrVoDrlwDjloDjVwDrVsDrl0DjlsDjV0DGKISpft9UwOF+6X6fVIDhfrKyhDukAjm+9AE5vrw+KX6Sf+NYAOl+0n/jWEDTl8DIDjCIJnCrWYDhf2tZwOF/K5oA6xpA2jJBPAPyQXwPskG8GvJB/B6TDzAziDQpQFIKfgJA4UBrmkDoAC5agOR/MjK0PdohQHuINAYmGX8ha6FLaX9aQCFr4UuTDzAqTOFAZhIivASrWoDoACR/MiR/MjQ+Ob9ytDzaKrwC61qA6AAkfzIytD6qTeFAUw8wKX80ALG/cb8pf1IpfxIqQhMucSiCL35wZ1AA8oQ96kDSKk/SKkITLnEIFmmIDOlTK6nQkNERk5PIFJSLU5FVCBGT1VORC4NAFJSLU5FVCBGT1VORC4gQ1M4OTAwQSBSRVZJU0lPTiAAogO9UgOdVgO9NAOdUgPKEPGpgI1OA6kAjVADjVEDhfqF+xiiEqX7fUcDhful+n1GA4X6ysoQ7pAI5vvQBOb68Pil+kn/jVADpftJ/41RA6IFvT4DnTgDvb/EnT4DyhDxYBitSQNpDqqtSANpANAEikxpxGBIohy9RgOdXgPKEPeiB6kAnVoDytD6hfqF+41IA6k0jUkDqQGNTwOpA41aA2iNWwMYoh6l+31bA4X7pfp9WgOF+srKEO6QCOb70ATm+vD4pfpJ/41cA6X7Sf+NXQMgOMJMmcKiB71Tw91GA9A5yhD1ogO9NAPdXgPQLMoQ9akCjU0Dogm9TgOdWAO9v8SdTgPKEPGiA700A51UA8oQ9yCHwqk8TGnEYAABCAAGBAABhvyE/SC5wxABYEip/4X6oACYSBhprCDtw4ol+oX6mCX6hfpoqMjAA9DnpfrJ/9AaoACx/KrImEix/KhoSEoJrCDcw2ioyMAG0OipgqIFoA8g3MOpiaLToAAg3MNoYKkAIO3D4A7QF8Bj0BOpASDtw4rQC8ALsAeYOOkHkAFgqf9gCo0C3qkAKo0D3o4E3owF3mAKjQLeqQAqjQPergTerAXeYKmSIO3DmCl/0AOp/2CtCd6tCN6sCd6uCN6Y0CngyLAlikoIqvAToACtCN6ZOAPIrQnemTgDyMrQ7yiQBq0I3pk4A6kAYIpImPAOogCtCN6tCd7o0PeI0PRoqvAMrQjeyvAGrQneytD0qf9gosmODN6iAI4N3o0O3o4P3kipkiDtw5gpf/ASrQnerQjerAnergjeIEPETHrEqZwg7cOYKQHw2mhKaQCqoAC5OAONCN7IuTgDjQneyMrQ72CpAI0g0GAAgBCxMhg= | base64 -d > /tmp/picview.prg");
else
os.execute("echo AQgLCAoAnjIwNjIAAAAArQDdKfwJAo0A3ak4jRjQqRiNFtCpO40R0K0/NY0h0KkAjSDQogC9Lw6dAGC9Lw+dAGG9LxCdAGK9LxGdAGO9LxKdAGS9LxOdAGW9LxSdAGa9LxWdAGe9LxadAGi9LxedAGm9LxidAGq9LxmdAGu9LxqdAGy9LxudAG29LxydAG69Lx2dAG/o4ADQm6IAvS8enQBwvS8fnQBxvS8gnQByvS8hnQBzvS8inQB0vS8jnQB1vS8knQB2vS8lnQB3vS8mnQB4vS8nnQB5vS8onQB6vS8pnQB7vS8qnQB8vS8rnQB9vS8snQB+vS8tnQB/6OAA0JuiAL1vLZ0ATL1vLp0ATb1vL50ATr1vMJ0AT+jgANDjvVcxnQDYvVcynQDZvVcznQDavVc0nQDb6OAA0OO9aAmdAMC9aAqdAMG9aAudAMK9aAydAMO9aA2dAMS9aA6dAMXo4ADQ10wAwKnAjTQDqaiNNQOpAI02A6lAjTcDrQHeCQGNAd6iv6DEIFvDEAmpBqDCqQhMucRIqRigwmipDXgg/sMQ+1gg4f/QA0y5xHgg/sMw8a1EA8kI0OqtRQPwCskG0OEgD8NMPMCtRgPJRdDUrUwDKb8NTQPQyq1PA8kR8DbJAfAIqQIgrMJMPMCtWgPJCNAgqQCNWgMYrVwDaQiNXAOQCu5dA9AF7lwD8PYgOMIgmcJMPMCtXAPJGdAHrV0DyT7wCKkDIKzCTDzArWIDycrQ4K1jA8kf0NmtZQNIqQGNZQOpAI1IA41eA41gA4X6hfupII1JA6kYjV8DqRGNYQOtWgOuXAOOWgONXAOtWwOuXQOOWwONXQMYohKl+31TA4X7pfp9UgOF+srKEO6QCOb70ATm+vD4pfpJ/41gA6X7Sf+NYQNOXwMgOMIgmcKtZgOF/a1nA4X8rmgDrGkDaMkE8A/JBfA+yQbwa8kH8HpMPMDOINClAUgp+AkDhQGuaQOgALlqA5H8yMrQ92iFAe4g0BiYZfyFroUtpf1pAIWvhS5MPMCpM4UBmEiK8BKtagOgAJH8yJH8yND45v3K0PNoqvALrWoDoACR/MjK0PqpN4UBTDzApfzQAsb9xvyl/Uil/EipCEy5xKIIvfnBnUADyhD3qQNIqT9IqQhMucQgWaYgM6VMrqdCQ0RGTk8gUlItTkVUIEZPVU5ELg0AUlItTkVUIEZPVU5ELiBDUzg5MDBBIFJFVklTSU9OIACiA71SA51WA700A51SA8oQ8amAjU4DqQCNUAONUQOF+oX7GKISpft9RwOF+6X6fUYDhfrKyhDukAjm+9AE5vrw+KX6Sf+NUAOl+0n/jVEDogW9PgOdOAO9v8SdPgPKEPFgGK1JA2kOqq1IA2kA0ASKTGnEYEiiHL1GA51eA8oQ96IHqQCdWgPK0PqF+oX7jUgDqTSNSQOpAY1PA6kDjVoDaI1bAxiiHqX7fVsDhful+n1aA4X6ysoQ7pAI5vvQBOb68Pil+kn/jVwDpftJ/41dAyA4wkyZwqIHvVPD3UYD0DnKEPWiA700A91eA9AsyhD1qQKNTQOiCb1OA51YA72/xJ1OA8oQ8aIDvTQDnVQDyhD3IIfCqTxMacRgAAEIAAYEAAGG/IT9ILnDEAFgSKn/hfqgAJhIGGmsIO3DiiX6hfqYJfqF+mioyMAD0Oel+sn/0BqgALH8qsiYSLH8qGhISgmsINzDaKjIwAbQ6KmCogWgDyDcw6mJotOgACDcw2hgqQAg7cPgDtAXwGPQE6kBIO3DitALwAuwB5g46QeQAWCp/2AKjQLeqQAqjQPejgTejAXeYAqNAt6pACqNA96uBN6sBd5gqZIg7cOYKX/QA6n/YK0J3q0I3qwJ3q4I3pjQKeDIsCWKSgiq8BOgAK0I3pk4A8itCd6ZOAPIytDvKJAGrQjemTgDqQBgikiY8A6iAK0I3q0J3ujQ94jQ9Giq8AytCN7K8AatCd7K0PSp/2CiyY4M3qIAjg3ejQ7ejg/eSKmSIO3DmCl/8BKtCd6tCN6sCd6uCN4gQ8RMesSpnCDtw5gpAfDaaEppAKqgALk4A40I3si5OAONCd7IytDvYKkAjSDQYACAELEyGA== | base64 -d > /tmp/picview.prg");
end
if picsize == 9000 or picsize == 10001 then -- check for loadaddress, add two bytes if not found
os.execute('echo a >> /tmp/picview.prg');
end
os.execute('cat '.. fp .. '/' .. fn .. ' >> /tmp/picview.prg'); -- append pic to c64 binary
os.execute("codenet -x /tmp/picview.prg -n "..ip); -- send file to c64
/data/common/media/grafx2/scripts/samples_2.4/demo/3DPalette.lua
0,0 → 1,460
--3D-Palette viewer V0.72 (HSL-models added, 3D-World added, Pen-color only cycles thru unique colors, InputBox)
--by Richard 'Dawnbringer' Fhager
 
-- Mouse: Rotate Cube (Stops animation)
-- Arrow-keys: Move Cube (in 3D world)
-- F1: Start/Stop animation
-- F2: Reset
-- F3: Increase Color-Size
-- F4: Decrease Color-Size
-- F5: (Wip) Cycle thru selected PenColor (Note that only unique colors are displayed)
-- F9: RGB-space model
--F10: HSL-space model
--F11: HSLcubic-space model
-- "+" (Num): Zoom In
-- "-" (Num): Zoom Out
-- Esc: Exit script
 
-- Drawing updated, rectangle missing, Sep11
 
run("../libs/dawnbringer_lib.lua")
 
 
BRIDIAG_SHOW = 1 -- Show brightness/Grayscale diagonal (1 = on, 0 = off)
ANIM = 1 -- Animation (1 = on, 0 = off)
BOX_DRK = 8 -- Darkest color used for box (0-255)
BOX_BRI = 112 -- Brightest color used for box (0-255)
COLSIZE_BASE = 26 -- Colors base size (value to adjusted by palette-size, with 2 cols maxsize is v / 1.23)
 
--
OK,RGB,HSL,HSLC,BOX_BRI,COLSIZE_BASE,SET800x600 = inputbox("3D-Palette Viewer Settings",
"1. RGB space [F9]", 1, 0,1,-1,
"2. HSL space [F10]", 0, 0,1,-1,
"3. HSL-cubic space [F11]",0, 0,1,-1,
"Box Brightness (16-255)", BOX_BRI, 16,255,0,
"Col Size (1-100) [F3/F4]", COLSIZE_BASE, 1,100,0,
"Set Screen to 800x600", 1,0,1,0
);
--
 
if OK then
 
if SET800x600 == 1 then setpicturesize(800,600); end
 
SPACE = "rgb"
FORM = "cube"
if HSL == 1 then
SPACE = "hsl"
FORM = "cylinder"
end
if HSLC == 1 then
SPACE = "hsl_cubic"
FORM = "cube"
end
 
 
pal = db.fixPalette(db.makePalList(256))
 
FG = getforecolor()
BG = getbackcolor()
 
palcol = FG
 
--
function initColors(space)
for n = 1, #pal, 1 do
c = pal[n];
if space == "rgb" then
cols[n] = {c[1]/128-1,c[2]/128-1,c[3]/128-1,c[4]};
end
if space == "hsl_cubic" then
cols[n] = {}
cols[n][1] = (db.getHUE(c[1],c[2],c[3],0) / 6.0 * 255) / 128 - 1
cols[n][2] = (db.getSaturation(c[1],c[2],c[3])) / 128 - 1
cols[n][3] = (db.getLightness(c[1],c[2],c[3])) / 128 - 1
cols[n][4] = c[4]
end
if space == "hsl" then
cols[n] = {}
hue = db.getHUE(c[1],c[2],c[3],0) / 6.0 * math.pi*2
rad = db.getSaturation(c[1],c[2],c[3]) / 256
cols[n][1] = math.cos(hue) * rad
cols[n][2] = math.sin(hue) * rad
cols[n][3] = (db.getLightness(c[1],c[2],c[3])) / 128 - 1
cols[n][4] = c[4]
end
end
end
--
 
cols = {} -- Make points of palette colors
colz = {} -- To hold calculated points
initColors(SPACE)
 
 
function initPointsAndLines(form,bridiag)
if form == "cube" then
pts = {{-1,1,-1},{1,1,-1},{1,-1,-1},{-1,-1,-1}, -- The box
{-1,1, 1},{1,1, 1},{1,-1, 1},{-1,-1, 1}}
lin = {{1,2},{2,3},{3,4},{4,1},{5,6},{6,7},{7,8},{8,5},{1,5},{2,6},{3,7},{4,8}} -- Box Lines
if bridiag == 1 then lin[13] = {4,6}; end
end
if form == "cylinder" then
p = 28
pts = {}
lin = {}
for n = 1, p, 1 do
x = math.cos(math.pi*2 / p * (n-1))
y = math.sin(math.pi*2 / p * (n-1))
pts[n] = {x,y,-1}
lin[n] = {n,1 + (n%p)}
pts[n + p] = {x,y,1}
lin[n + p] = {n+p,p + 1 + (n%p)}
end
lin[p*2+1] = {1,p+1} -- Red (0 degrees)
lin[p*2+2] = {p+1,p+1+math.ceil(p/2)} -- Lightness end (needs an even # of points to work)
end
end
 
boxp = {} -- To hold the calculated points
initPointsAndLines(FORM,BRIDIAG_SHOW)
 
w,h = getpicturesize()
CX,CY = w/2, h/2
 
 
 
function initAndReset()
XANG, YANG, ZANG, ZOOM, COLSIZE_ADJ, XD, YD, WORLD_X, WORLD_Y, ZSELECT = 0,0,0,0,0,0,0,0,0,0
end
 
initAndReset()
 
SIZE = math.min(w,h)/4
DIST = 5 -- Distance perspective modifier, ~5 is nominal, more means "less 3D"
 
CMAXSIZE = math.floor(COLSIZE_BASE / ((#pal)^0.3))
--CMAXSIZE = 8
CMINSIZE = 1 -- Negative values are ok. Color are never smaller than 1 pix
 
BOX_LINE_DIV = 20 -- Number of colors/segments that a box-line can be divided into (depth)
BOX_DIV_MULT = BOX_LINE_DIV / (math.sqrt(3)*2)
 
-- Box depth colors
box_div = {}
for n = 0, BOX_LINE_DIV-1, 1 do
c = BOX_DRK + (BOX_BRI / (BOX_LINE_DIV - 1)) * n
--box_div[BOX_LINE_DIV - n] = matchcolor(c,c,c)
box_div[BOX_LINE_DIV - n] = db.getBestPalMatchHYBRID({c,c,c},pal,0.5,true)
end
 
--BOX_COL = matchcolor(80,80,80)
BKG_COL = matchcolor(0,0,0)
--CUR_COL = matchcolor(112,112,112)
 
 
function rotate3D(x,y,z,Xsin,Ysin,Zsin,Xcos,Ycos,Zcos) -- PrecCalced cos&sin for speed
 
local x1,x2,x3,y1,y2,y3,f,xp,yp
 
x1 = x
y1 = y * Xcos + z * Xsin
z1 = z * Xcos - y * Xsin
 
x2 = x1 * Ycos - z1 * Ysin
y2 = y1
z2 = x1 * Ysin + z1 * Ycos
 
x3 = x2 * Zcos - y2 * Zsin
y3 = x2 * Zsin + y2 * Zcos
z3 = z2
 
return x3,y3,z3
end
 
function do3D(x,y,z,zoom,dist,Xsin,Ysin,Zsin,Xcos,Ycos,Zcos) -- PrecCalced cos&sin for speed
 
local x1,x2,x3,y1,y2,y3,f,xp,yp
 
x1 = x
y1 = y * Xcos + z * Xsin
z1 = z * Xcos - y * Xsin
 
x2 = x1 * Ycos - z1 * Ysin
y2 = y1
z2 = x1 * Ysin + z1 * Ycos
 
x3 = x2 * Zcos - y2 * Zsin
y3 = x2 * Zsin + y2 * Zcos
z3 = z2
 
f = dist/(z3 + dist + zoom)
xp = x3 * f
yp = y3 * f
 
return xp,yp,z3
end
 
 
function draw3Dline(x1,y1,z1,x2,y2,z2,div,mult,depthlist)
local s,xt,yt,xd,yd,zd,xf,yf
xd = (x2 - x1) / div
yd = (y2 - y1) / div
zd = (z2 - z1) / div
xf,yf = x1,y1
 
for s = 1, div, 1 do
-- Depth assumes a 1-Box (z ranges from -sq(3) to sq(3))
depth = math.floor(1 + (z1+zd*s + 1.732) * mult)
xt = x1 + xd*s -- + math.random()*8
yt = y1 + yd*s -- + math.random()*8
c = depthlist[depth]
if c == null then c = 1; end -- Something isn't perfect, error is super rare but this controls it
--db.line(xf,yf,xt,yt,c)
drawline(xf,yf,xt,yt,c)
xf = xt
yf = yt
end
end
 
function killinertia()
XD = 0
YD = 0
end
 
-- If using 1-box, z is -sq(3) to sq(3)
minz = math.sqrt(3)
totz = minz * 2
maxrad = CMAXSIZE - CMINSIZE
 
--q = 0
--delay = 4
--move = 0.03
 
while 1 < 2 do
 
-- Time-for-space-wiggle...or somekindof attempt
--WORLD_X = -move
--q = (q + 1) % delay
--if q < delay/2 then WORLD_X = move; end
 
clearpicture(BKG_COL)
 
Xsin = math.sin(XANG); Xcos = math.cos(XANG)
Ysin = math.sin(YANG); Ycos = math.cos(YANG)
Zsin = math.sin(ZANG); Zcos = math.cos(ZANG)
 
-- Rotate Box points
for n = 1, #pts, 1 do
p = pts[n]
x,y,z = p[1],p[2],p[3]
XP,YP,zp = rotate3D(x,y,z,Xsin,Ysin,Zsin,Xcos,Ycos,Zcos)
boxp[n] = {XP,YP,zp}
end
 
-- Rotate Colors in palette
for n = 1, #cols, 1 do
p = cols[n]
x,y,z,c = p[1],p[2],p[3],p[4]
XP,YP,zp = rotate3D(x,y,z,Xsin,Ysin,Zsin,Xcos,Ycos,Zcos)
colz[n] = {XP,YP,zp,c}
end
 
------------------------------------
-- Control world
------------------------------------
 
-- Calculate points anew
 
-- Worldize Box points
for n = 1, #boxp, 1 do
s = SIZE
v = boxp[n]
x = v[1] + WORLD_X
y = v[2] + WORLD_Y
z = v[3]
f = DIST/(z + DIST + ZOOM)
XP = CX + x * f * s
YP = CY + y * f * s
boxp[n] = {XP,YP,z}
end
 
-- Worldize Colors in palette
for n = 1, #colz, 1 do
s = SIZE
v = colz[n]
x = v[1] + WORLD_X
y = v[2] + WORLD_Y
z = v[3]
c = v[4]
f = DIST/(z + DIST + ZOOM)
XP = CX + x * f * s
YP = CY + y * f * s
colz[n] = {XP,YP,z,c}
end
 
 
-------------------------------------
-------------------------------------
 
-- Brightness Diagonal
--if BRIDIAG_SHOW == 1 then
-- p1 = boxp[4]
-- p2 = boxp[6]
-- x1,y1,z1 = p1[1],p1[2],p1[3]
-- x2,y2,z2 = p2[1],p2[2],p2[3]
-- draw3Dline(x1,y1,z1,x2,y2,z2,BOX_LINE_DIV,BOX_DIV_MULT,box_div)
--end
 
--c1 = math.min(FG,BG)
--c2 = math.max(FG,BG)
--p = colz[26]
--XP1,YP1,zp1,c1 = p[1],p[2],p[3],p[4]
--for n = #colz, 1, -1 do
-- p = colz[27]
-- XP2,YP2,zp2,c2 = p[1],p[2],p[3],p[4]
-- drawline(XP1,YP1,XP2,YP2,c1)
--end
 
-- sort on z
db.sorti(colz,3)
 
-- Draw colors
for n = #colz, 1, -1 do
p = colz[n]
XP,YP,zp,c = p[1],p[2],p[3],p[4]
 
radius = CMINSIZE + maxrad - (zp+minz) / totz * maxrad
dorad = math.floor(radius - ZOOM*2 + COLSIZE_ADJ)
 
if dorad >= 1 then
--db.drawCircle(XP,YP,dorad,c)
drawdisk(XP,YP,dorad,c)
--db.drawRectangle(XP,YP,dorad,dorad,c)
else putpicturepixel(XP,YP,c)
end
 
if c == FG or c == BG then
sz = math.max(3,dorad + 3)
if c == BKG_COL then v = (c+128) % 255; c = matchcolor(v,v,v); end
db.drawRectangleLine(XP-sz,YP-sz,sz*2,sz*2,c)
end
 
end -- colz
 
 
 
-- Draw box
for n = 1, #lin, 1 do
l = lin[n]
p1 = boxp[l[1]]
p2 = boxp[l[2]]
x1,y1,z1 = p1[1],p1[2],p1[3]
x2,y2,z2 = p2[1],p2[2],p2[3]
draw3Dline(x1,y1,z1,x2,y2,z2,BOX_LINE_DIV,BOX_DIV_MULT,box_div)
 
end -- eof box
 
--updatescreen(); if (waitbreak(0.00)==1) then return; end
 
repeat
 
old_key = key;
old_mouse_x = mouse_x;
old_mouse_y = mouse_y;
old_mouse_b = mouse_b;
updatescreen()
moved, key, mouse_x, mouse_y, mouse_b = waitinput(0)
if mouse_b == 1 then ANIM = 0; end
 
if (key==27) then
return;
end
 
if (key==282) then ANIM = (ANIM+1) % 2; end -- F1: Stop/Start Animation
if (key==283) then initAndReset(); end -- F2: Reset all values
if (key==284) then COLSIZE_ADJ = COLSIZE_ADJ + 0.5; end -- F3
if (key==285) then COLSIZE_ADJ = COLSIZE_ADJ - 0.5; end -- F4
 
--messagebox(key)
 
if (key==286) then
--FG = (FG + 1) % 255;
palcol = (palcol + 1) % #pal
FG = pal[palcol+1][4]
setforecolor(FG);
setcolor(0,getcolor(0)) -- Force update of palette until setforecolor() is fixed
end -- F5
 
if (key==290) then -- F9
initColors("rgb")
initPointsAndLines("cube",BRIDIAG_SHOW)
end
if (key==291) then -- F10
initColors("hsl")
initPointsAndLines("cylinder", 0) -- Bridiag won't show even if turned on, it's only for cube
end
if (key==292) then -- F11
initColors("hsl_cubic")
initPointsAndLines("cube",BRIDIAG_SHOW)
end
 
if (key==269) then ZOOM = ZOOM + 0.1; end
if (key==270) then ZOOM = ZOOM - 0.1; end
 
if (key==32) then
ZSELECT = (ZSELECT + math.pi/2) % (2*math.pi);
--YANG = ((YANG - math.pi/2) % (math.pi*2));
--XANG = ((XANG + math.pi/2) % (math.pi*2));
 
YANG = ((YANG + math.pi/2) % (math.pi*2));
XANG = ((XANG + math.pi/2) % (math.pi*2));
YANG = ((YANG - math.pi/2) % (math.pi*2));
end -- Rotate Z 90 Degrees
 
SPEED = math.pi / 100
 
if (key==273) then WORLD_Y = WORLD_Y - 0.05; killinertia(); end
if (key==274) then WORLD_Y = WORLD_Y + 0.05; killinertia(); end
 
if (key==276) then WORLD_X = WORLD_X - 0.05; killinertia(); end
if (key==275) then WORLD_X = WORLD_X + 0.05; killinertia(); end
until ((mouse_b == 1 and (old_mouse_x~=mouse_x or old_mouse_y~=mouse_y)) or key~=0 or ANIM==1 or math.abs(XD)>0.01 or math.abs(YD)>0.01);
 
if ANIM == 0 then
if (mouse_b==1 and (old_mouse_x~=mouse_x or old_mouse_y~=mouse_y)) then -- Inertia
XD = (mouse_y - old_mouse_y)*0.005
YD = (mouse_x - old_mouse_x)*0.005
else
XD = XD*0.92
YD = YD*0.92
end
XANG = ((XANG - XD) % (math.pi*2));
YANG = ((YANG + YD) % (math.pi*2));
ZANG = ZSELECT
end
 
if ANIM == 1 then
XANG = (XANG + math.pi/300) % (math.pi*2)
YANG = (YANG + math.pi/500) % (math.pi*2)
ZANG = (ZANG + math.pi/1000) % (math.pi*2)
end
 
--XANG = ((CY-mouse_y) / 200 % (math.pi*2));
--YANG = ((mouse_x - CX) / 200 % (math.pi*2));
--ZANG = 0
 
statusmessage("x"..math.floor(XANG*57.3).."° y"..math.floor(YANG*57.3).."° z"..math.floor(ZANG*57.3).."° Zm: "..math.floor(-ZOOM*10).." ")
 
end
 
end -- OK
/data/common/media/grafx2/scripts/samples_2.4/demo/Ellipse.lua
0,0 → 1,68
--PICTURE scene: Ellipse update-demo (anim)
--Demonstrates 'interactive' features.
--by Richard Fhager
 
-- Copyright 2011 Richard Fhager
--
-- 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; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
 
--
-- rot: Rotation in degrees
-- stp: Step is # of line segments (more is "better")
-- a & b are axis-radius
function ellipse2(x,y,a,b,stp,rot,col)
local n,m=math,rad,al,sa,ca,sb,cb,ox,oy,x1,y1,ast
m = math; rad = m.pi/180; ast = rad * 360/stp;
sb = m.sin(-rot * rad); cb = m.cos(-rot * rad)
for n = 0, stp, 1 do
ox = x1; oy = y1;
sa = m.sin(ast*n) * b; ca = m.cos(ast*n) * a
x1 = x + ca * cb - sa * sb
y1 = y + ca * sb + sa * cb
if (n > 0) then drawline(ox,oy,x1,y1,col); end
end
end
--
 
setpicturesize(300,300)
setcolor(0,96,96,96)
setcolor(1,255,255,128)
 
r1 = 100
r2 = 50
rt = 0
 
frames = 100
 
 
while (1 < 2) do
 
r1t = 10 + math.random() * 140
r2t = 10 + math.random() * 140
rtt = math.random() * 360
 
for n = 0, frames-1, 1 do
clearpicture(0)
 
f2 = n / frames
f1 = 1 - f2
 
r1a = r1*f1 + r1t*f2
r2a = r2*f1 + r2t*f2
rta = rt*f1 + rtt*f2
 
-- x, y, r1, r2, stp, rot, col
ellipse2(150, 150, r1a, r2a, 50, rta, 1)
 
statusmessage('press ESC to stop')
updatescreen();if (waitbreak(0)==1) then return end
 
end
 
r1,r2,rt = r1a,r2a,rta
 
end
/data/common/media/grafx2/scripts/samples_2.4/demo/FlipPicture.lua
0,0 → 1,17
-- flip picture - Copyright 2010 Paulo Silva
-- 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; version 2 of the License. See <http://www.gnu.org/licenses/>
w,h=getpicturesize();
ok,flipx,flipy=inputbox("flip picture","flip x",1,0,1,-1,"flip y",0,0,1,-1);
if ok==true then
if flipx==1 then
for y=0,h-1,1 do
for x=0,w/2,1 do
c1=getpicturepixel(x,y);c2=getpicturepixel(w-x-1,y)
putpicturepixel(x,y,c2);putpicturepixel(w-x-1,y,c1)
end;end
else
for y=0,h/2,1 do
for x=0,w-1,1 do
c1=getpicturepixel(x,y);c2=getpicturepixel(x,h-y-1)
putpicturepixel(x,y,c2);putpicturepixel(x,h-y-1,c1)
end;end;end;end
/data/common/media/grafx2/scripts/samples_2.4/demo/SierpinskyCarpet.lua
0,0 → 1,59
--PICTURE: Pattern - Sierpinsky carpet v1.0
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
-- Email: dawnbringer@hem.utfors.se
-- MSN: annassar@hotmail.com
--
-- Copyright 2010 Richard Fhager
--
-- 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; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
-- This script was adopted from Evalion, a Javascript codecrafting/imageprocessing project
-- http://goto.glocalnet.net/richard_fhager/evalion/evalion.html
--
 
frac = {{1,1,1},{1,0,1},{1,1,1}}
 
iter = 6
 
 
--
function pattern(x,y,p,n,i) -- Fractal Pattern V1.0 by Richard Fhager (mod allows for wrapping)
py = #p
px = #p[1]
while ((p[1+math.abs(math.floor(y*py))%py][1+math.abs(math.floor(x*px))%px]) == 1 and n<i) do
x=x*px-math.floor(x*px);
y=y*py-math.floor(y*py);
n = n+1
end
return 1 - n/i;
end
--
 
w, h = getpicturesize()
 
rp,gp,bp = getcolor(getforecolor())
 
 
for y = 0, h - 1, 1 do
for x = 0, w - 1, 1 do
 
ox = x / w;
oy = y / h;
 
f = pattern(ox,oy,frac,0,iter);
 
c = matchcolor(rp*f,gp*f,bp*f)
 
putpicturepixel(x, y, c);
end
updatescreen()
if (waitbreak(0)==1) then
return
end
 
end
 
/data/common/media/grafx2/scripts/samples_2.4/demo/SierpinskyTriangle.lua
0,0 → 1,57
--PICTURE: Pattern - Sierpinsky triangle v1.0
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
-- Email: dawnbringer@hem.utfors.se
-- MSN: annassar@hotmail.com
--
-- Copyright 2010 Richard Fhager
--
-- 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; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
-- This script was adopted from Evalion, a Javascript codecrafting/imageprocessing project
-- http://goto.glocalnet.net/richard_fhager/evalion/evalion.html
--
 
frac = {{1,1},{1,0}}
 
iter = 15
 
--
function pattern(x,y,p,n,i) -- Fractal Pattern V1.0 by Richard Fhager (mod allows for wrapping)
py = #p
px = #p[1]
while ((p[1+math.abs(math.floor(y*py))%py][1+math.abs(math.floor(x*px))%px]) == 1 and n<i) do
x=x*px-math.floor(x*px);
y=y*py-math.floor(y*py);
n = n+1
end
return 1 - n/i;
end
--
 
w, h = getpicturesize()
 
rp,gp,bp = getcolor(getforecolor())
 
for y = 0, h - 1, 1 do
for x = 0, w - 1, 1 do
 
ox = x / w;
oy = y / h;
 
f = pattern(ox,oy,frac,0,iter);
 
c = matchcolor(rp*f,gp*f,bp*f)
 
putpicturepixel(x, y, c);
 
end
updatescreen()
if (waitbreak(0)==1) then
return
end
end
 
/data/common/media/grafx2/scripts/samples_2.4/demo/Spritesheet.lua
0,0 → 1,46
--ANIM: Sprite Animator v0.15
--Spare page holds data - Plays on current
--by Richard Fhager
 
run("../libs/memory.lua")
 
arg=memory.load({XS=16,YS=16,SPACE=1,FRAMES=8,XOFF=0,YOFF=0,FPS=10})
 
OK, XS, YS, SPACE, FRAMES, XOFF, YOFF, FPS = inputbox("Sprite-Sheet Animator",
"Sprite X-size", arg.XS, 1, 256,0,
"Sprite Y-size", arg.YS, 1, 256,0,
"Spacing", arg.SPACE, 0, 32,0,
"# of Frames", arg.FRAMES,2, 100,0,
"X-offset", arg.XOFF, 0, 800,0,
"Y-offset", arg.YOFF, 0, 800,0,
"Play Speed (FPS)",arg.FPS, 1, 60,0
);
 
 
if OK == true then
 
memory.save({XS=XS,YS=YS,SPACE=SPACE,FRAMES=FRAMES,XOFF=XOFF,YOFF=YOFF,FPS=FPS})
 
MAXPLAYS = 100
 
w,h = getpicturesize()
OX = w / 2 - XS/2
OY = h / 2 - YS/2
 
for play = 1, MAXPLAYS, 1 do
 
for f = 0, FRAMES-1, 1 do
for y = 0, YS-1, 1 do
for x = 0, XS-1, 1 do
sx = x + XOFF + f * (XS + SPACE)
sy = y + YOFF
putpicturepixel(OX+x, OY+y, getsparepicturepixel(sx, sy))
end
end
updatescreen(); if (waitbreak(1/FPS)==1) then return; end
end
 
end -- plays
 
end --OK
 
/data/common/media/grafx2/scripts/samples_2.4/demo/brush/Amigaball.lua
0,0 → 1,57
--BRUSH Scene: Amigaball 1.0
--
--Draws the famous 'Amiga ball' in the brush.
--
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
 
-- Copyright 2010 Richard Fhager
--
-- 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; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
-- This script was adopted from Evalion, a Javascript codecrafting/imageprocessing project
--http://goto.glocalnet.net/richard_fhager/evalion/evalion.html
 
 
 
w, h = getbrushsize()
if (w<64 or h<64) then
setbrushsize(64,64)
w=64
h=64
end
 
for y = 0, h - 1, 1 do
for x = 0, w - 1, 1 do
 
-- Fractionalize image dimensions
ox = x / w;
oy = y / h;
 
-- Ball
Xr = ox-0.5; Yr = oy-0.5;
W = (1 - 2*math.sqrt(Xr*Xr + Yr*Yr));
 
-- 'FishEye' distortion / Fake 3D
F = (math.cos((ox-0.5)*math.pi)*math.cos((oy-0.5)*math.pi))*0.65;
ox = ox - (ox-0.5)*F;
oy = oy - (oy-0.5)*F;
 
-- Checkers
V = ((math.floor(0.25+ox*10)+math.floor(1+oy*10)) % 2) * 255 * W;
 
-- Specularities
SPEC1 = math.max(0,(1-5*math.sqrt((ox-0.45)*(ox-0.45)+(oy-0.45)*(oy-0.45)))*112);
SPEC2 = math.max(0,(1-15*math.sqrt((ox-0.49)*(ox-0.49)+(oy-0.48)*(oy-0.48)))*255);
 
r = W * 255 + SPEC1 + SPEC2
g = V + SPEC1 + SPEC2
b = V + SPEC1 + SPEC2
 
putbrushpixel(x, y, matchcolor(r,g,b));
 
end
end
/data/common/media/grafx2/scripts/samples_2.4/demo/brush/ColorSphere.lua
0,0 → 1,38
--BRUSH Scene: Sphere of pencolor v1.0
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
 
-- Copyright 2010 Richard Fhager
--
-- 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; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
-- This script was adopted from Evalion, a Javascript codecrafting/imageprocessing project
--http://goto.glocalnet.net/richard_fhager/evalion/evalion.html
 
 
w, h = getbrushsize()
 
rp,gp,bp = getcolor(getforecolor())
 
for y = 0, h - 1, 1 do
for x = 0, w - 1, 1 do
 
-- Fractionalize image dimensions
ox = x / w;
oy = y / h;
 
-- Sphere
X = 0.5; Y = 0.5; Rd = 0.5
a = math.sqrt(math.max(0,Rd*Rd - ((X-ox)*(X-ox)+(Y-oy)*(Y-oy)))) * 1/Rd
r = rp * a
g = gp * a
b = bp * a
 
putbrushpixel(x, y, matchcolor(r,g,b));
 
end
end
/data/common/media/grafx2/scripts/samples_2.4/demo/brush/FindAA.lua
0,0 → 1,100
--BRUSH: Find AA-colors from pencolors
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
 
-- Copyright 2010 Richard Fhager
--
-- 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; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
cellw = 8
cellh = 4
colors = 256
 
setbrushsize(cellw * 3, cellh * 3)
 
 
--
function makePalList(cols)
pal = {}
for n = 0, cols-1, 1 do
r,g,b = getcolor(n)
pal[n+1] = {r,g,b}
end
return pal
end
--
 
--
function getBestPalMatchHYBRID(rgb,pal,briweight)
local diff,diffC,diffB,best,bestcol,cols,n,c,r,g,b,p,obri,pbri
cols = #pal
bestcol = 0
best = 9e99
 
r = rgb[1]
g = rgb[2]
b = rgb[3]
 
obri = math.pow(r*9,2)+math.pow(g*16,2)+math.pow(b*8,2)
 
for n=0, cols-1, 1 do
p = pal[n+1]
pbri = math.pow(p[1]*9,2)+math.pow(p[2]*16,2)+math.pow(p[3]*8,2)
diffB = math.abs(obri - pbri)
 
 
diffC = (math.pow(r-p[1],2)+math.pow(g-p[2],2)+math.pow(b-p[3],2)) * 400
--diff = diffB + diffC
diff = briweight * (diffB - diffC) + diffC
if diff <= best then bestcol = n; best = diff; end
end
 
return bestcol
end
--
 
--
function drawRectangle(x1,y1,w,h,c)
for y = y1, y1+h, 1 do
for x = x1, x1+w, 1 do
putbrushpixel(x,y,c);
end
end
end
--
 
 
 
palList = makePalList(colors)
 
cf = getforecolor()
cb = getbackcolor()
rf,gf,bf = getcolor(cf)
rb,gb,bb = getcolor(cb)
 
ra = (rf + rb) / 2
ga = (gf + gb) / 2
ba = (bf + bb) / 2
 
rgb1 = {ra,ga,ba}
c1 = getBestPalMatchHYBRID(rgb1,palList,0.0)
c2 = getBestPalMatchHYBRID(rgb1,palList,0.75)
c3 = getBestPalMatchHYBRID(rgb1,palList,0.99)
 
q = {{cf,c1,cb},
{cf,c2,cb},
{cf,c3,cb}}
 
 
for y = 0, #q-1, 1 do
for x = 0, #q[1]-1, 1 do
drawRectangle(x*cellw,y*cellh,cellw,cellh,q[y+1][x+1])
 
end
end
 
 
/data/common/media/grafx2/scripts/samples_2.4/demo/brush/Mandelbrot.lua
0,0 → 1,64
--BRUSH Scene: Mandelbrot fractal v0.5
--
--Draws a Mandelbrot fractal in the current brush.
--
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
 
-- Copyright 2010 Richard Fhager
--
-- 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; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
-- This script was adopted from Evalion, a Javascript codecrafting/imageprocessing project
--http://goto.glocalnet.net/richard_fhager/evalion/evalion.html
 
 
colors = 64
 
x0 = -1.7
x1 = 0.7
ym = 0
iter = 64
 
 
ok, x0, x1, ym, iter = inputbox("Fractal data",
"X0", x0, -2, 2,4,
"X1", x1, -2, 2,4,
"midY", ym, -2, 2,4,
"Iter", iter, 1, 2048,0
);
 
-- -0.831116819,-0.831116815,0.2292112435,192
 
 
function mandel(x,y,l,r,o,i) -- pos. as fraction of 1, left coord, right coord, y coord, iterations
 
local w,s,a,p,q,n,v,w
 
s=math.abs(r-l);
 
a = l + s*x;
p = a;
b = o - s*(y-0.5);
q = b;
n = 1;
v = 0;
w = 0;
 
while (v+w<4 and n<i) do n=n+1; v=p*p; w=q*q; q=2*p*q+b; p=v-w+a; end;
 
return n
end
 
 
w, h = getbrushsize()
 
for x = 0, w - 1, 1 do
for y = 0, h - 1, 1 do
q = mandel(x/w,y/h,x0,x1,ym,iter) % colors;
putbrushpixel(x, y, q);
end
end
/data/common/media/grafx2/scripts/samples_2.4/libs/dawnbringer_lib.lua
0,0 → 1,3720
--DawnBringer function library v1.14 (some drawing replaced)
--** THIS IS NOT A RUNNABLE SCRIPT! **
--by Richard Fhager
-- http://hem.fyristorg.com/dawnbringer/
-- Email: dawnbringer@hem.utfors.se
-- MSN: annassar@hotmail.com
--
-- Many functions in here was adopted from Evalion, a Javascript codecrafting/imageprocessing project
-- http://goto.glocalnet.net/richard_fhager/evalion/evalion.html
--
--
-- You may access these functions in your own scripts by loading this library,
-- just add the follwing line as one of the first instructions:
--
-- run("dawnbringer_lib")
--
-- or
--
-- run("../libs/dawnbringer_lib.lua")
--
--
-- Note that the functions must be called with the full library object-name, "db.function_name..."
--
 
-- Global library object
db = {}
 
 
-- *************************************
-- *** Text & Conversions ***
-- *************************************
--
--
 
function db.rgb2HEX(r,g,b,prefix)
local c,n,s,t,z
c = {r,g,b}
z = {"0",""}
t = ""
for n = 1, 3, 1 do
s = string.upper(string.format("%x",c[n]))
t = t..z[#s]..s
--s = tonumber(c[n],16)
--t = t..s
end
return prefix..t
end
 
 
--
-- ... eof Text & Conversions ...
--
 
 
 
-- *************************************
-- *** Custom Math Functions ***
-- *************************************
--
--
function db.sign(v)
local s
s = 0
if v > 0 then s = 1; end
if v < 0 then s = -1; end
return s
end
--
 
function db.distance(ax,ay,bx,by) return math.sqrt((ax-bx)^2 + (ay-by)^2); end
 
--
function db.rotation (rot_ang,hub_x,hub_y,x,y) -- Rotate coordinates x & y relative hub
local new_ang,dist,m,xd,yd,v; m = math
xd=hub_x-x;
yd=hub_y-y;
if (not(xd==0 and yd==0)) then
v = -90; if xd < 0 then v = 90; end
new_ang = m.atan(yd/xd) - (v+rot_ang) * m.pi/180;
dist = m.sqrt(xd*xd+yd*yd);
x = hub_x - m.sin(new_ang)*dist;
y = hub_y + m.cos(new_ang)*dist;
end
return math.floor(x),math.floor(y) -- For drawing purposes
end
--
 
--
function db.recursiveSum(div,rlev) -- divisons per recursion,recursion levels
local s,i,m
s,m = 1,1
for i = 1, rlev, 1 do
m = m*div
s = s + m
end
return s
end
--
 
--
-- ... eof Custom Math Functions ...
--
 
-- *************************************
-- *** Fractional Scenery ***
-- *************************************
 
--
function db.setSceneryPalette()
db.colorCigarr(10,28,true) -- 250 colors
setcolor(250, 208,48,48)
setcolor(251, 48,208,48)
setcolor(252, 48,48,208)
setcolor(253, 224,224,64)
setcolor(254, 224,64,224)
setcolor(255, 64,224,224)
end
--
 
--
function db.star(xf,yf,sx,sy,rgb,haz,out,lum)
local n,c,dist; c={}
dist = haz + out * math.sqrt((xf-sx)^2+(yf-sy)^2);
for n = 1, 3, 1 do c[n] = (rgb[n] * lum) / dist; end
return c;
end
--
 
--
function db.zoom(xf,yf,zoom,panx,pany) -- Zoom and Pan in a fractional coord-system
xf = (xf-0.5)/zoom + 0.5 + panx;
yf = (yf-0.5)/zoom + 0.5 + pany;
return xf,yf
end
--
 
--
function db.rotationFrac(rot_ang,hub_x,hub_y,x,y) -- Rotate coordinates x & y relative hub
local new_ang,dist,m,xd,yd,v; m = math
xd=hub_x-x;
yd=hub_y-y;
if (not(xd==0 and yd==0)) then
v = -90; if xd < 0 then v = 90; end
new_ang = m.atan(yd/xd) - (v+rot_ang) * m.pi/180;
dist = m.sqrt(xd*xd+yd*yd);
x = hub_x - m.sin(new_ang)*dist;
y = hub_y + m.cos(new_ang)*dist;
end
return x,y
end
--
 
--
function db.twirl(x,y,arms,trot,tpow,tang)
local b,ang,vx,vy,vr,m,deg,tw
m=math; deg=math.pi/180; tw=.5;
if (not(x==.5 and y==.5)) then
ang = m.atan((.5-y)/(.5-x));
b = 0; if (x>.5) then b = m.pi; end
vx = .5-x; vy = .5-y; vr = m.pow(m.sqrt(vx*vx+vy*vy),tpow);
tw = .5+m.sin(-tang*deg+vr*trot+(ang + b)*arms)*.5;
end
return tw;
end
--
 
--- Alpha filters
--
function db.alpha1(x,y,amp) -- Coord, Amplify: 0..n
local p,a,xh,yh,m
xh=0.5-x; yh=0.5-y; m = math
p = m.pow(xh*xh+yh*yh,0.7);
a = m.cos(32*m.pi*p)*m.sin(8*m.pi*(xh+yh));
return 1 + (a * amp)
end
--
 
--
-- ... eof Fractional Scenery ...
--
 
-- *************************************
-- *** Custom Array Functions ***
-- *************************************
--
-- Ok, I don't know Lua that well (still unsure about some scopes & refs etc.)
-- And some features may not be active in Grafx2. So, some of the follwing functions
-- may exist in Lua/Grafx2...but since I'm not sure if and how they work - I'll prefer
-- to add a set of my own of known performance.
 
--
function db.newArrayInit(xs,val)
local x,ary; ary = {}
for x = 1, xs, 1 do
ary[x] = val
end
return ary
end
--
 
 
--
function db.newArrayInit2Dim(xs,ys,val)
local x,y,ary; ary = {}
for y = 1, ys, 1 do
ary[y] = {}
for x = 1, xs, 1 do
ary[y][x] = val
end
end
return ary
end
--
 
--
-- Merge two arrays into a NEW one: array_c = db.newArrayMerge(array_b,array_b)
--
function db.newArrayMerge(a,b)
local n,ary; ary = {}
for n = 1, #a, 1 do
ary[n] = a[n]
end
for n = 1, #b, 1 do
ary[n+#a] = b[n]
end
return ary
end
--
 
--
-- Generate a copy of an array with a new value added Last
--
function db.newArrayInsertLast(a,val)
local n,ary; ary = {}
for n = 1, #a, 1 do
ary[n] = a[n]
end
ary[#a+1] = val
return ary
end
--
 
--
-- Generate a copy of an array with a new value added First
--
function db.newArrayInsertFirst(a,val)
local n,ary; ary = {}
ary[1] = val
for n = 2, #a+1, 1 do
ary[n] = a[n-1]
end
return ary
end
--
 
--
function db.ary2txt(ary) -- One & two dimensions supported [a,b] -> "a,b". [[a,b],[c,d]] -> "a-b, c-d"
local t,n,m,v
t = ""
for n = 1, #ary, 1 do
if type(ary[n]) == "table" then
t = t..ary[n][1]
for m = 2, #ary[n], 1 do
t = t.."-"..ary[n][m]
end
else t = t..ary[n];
end
t = t..", "
end
return t
end
--
 
--
-- *** Array data manipulation ***
--
 
--
-- InsertionSort Array, this is chaos...I'm confused and stomped...don't understand how Lua works...
-- ...sorting seem be to ok but this code is ugly...
-- Sort LO-HI
--
-- Screwed up or confused thing here I think, perhaps lo-hi/hi-lo. This is working lo-hi but the code
-- looks like hi-lo...edit this some day
--
function db.sorti(d,idx)
local a,j,tmp,l,e
l = #d
 
for a=2, l, 1 do
tmp = d[a];
e = a
for j=a, 2, -1 do
e = j
if d[j-1][idx] > tmp[idx] then d[j] = d[j-1]; e = j-1; else break; end;
end;
d[e] = tmp; -- WHY THE F**K CAN'T YOU READ j HERE!?! STUPID ASSUCKING LANGUAGE
end;
--return d
end
--
 
--
function db.shuffle(list)
local i,n,t
for n = #list, 2, -1 do
i = 1+math.floor(math.random() * n)
t = list[n]; list[n] = list[i]; list[i] = t
end
end
--
 
--
-- ... eof Custom Array Functions ...
--
 
 
-- *************************************
-- *** Misc. Logical Operations ***
-- *************************************
 
--
-- palList [r,g,b,palindex] is expected only to contain unique colors
-- index = -1 --> index of list
--
function db.makeIndexList(list,index)
local n,ilist
ilist = {}
for n = 1, #list, 1 do
if (index > 0) then ilist[n] = list[n][index]; end
if (index == -1) then ilist[n] = n; end
end
return ilist
end
--
 
--
-- Return a list of all possible (non-same) pairs from the entries in a list
-- [a,b,c] --> [[a,b],[a,c],[b,c]]
-- (All entries are treated as unique. i.e it's only the INDEX that counts)
-- mode = 0: Only unique pairs (m = (n^2 - n)/2), [a,b] --> [[a,b]]
-- mode = 1: All pairs, i.e mirror versions as well. (m = n^2 - n), [a,b] --> [[a,b], [b,a]]
--
function db.pairsFromList(list,mode)
local a,b,l,n,pairs
pairs = {}
l = #list
n = 1
for a = 1, l, 1 do
for b = a+1, l, 1 do
pairs[n] = {list[a],list[b]}; n = n + 1
if mode == 1 then pairs[n] = {list[b],list[a]}; n = n + 1; end
end
end
return pairs
end
--
 
function db.valueInArray(ary,val)
local n,res
res = false
for n = 1, #ary, 1 do
if ary[n] == val then res = true; break; end
end
return res
end
 
-- RAMP specific
 
-- Remove initial pair (palList) colors from pallist
function db.initiateRamp(pair,pallist,pal_index)
local n,found,plist
plist = {}
 
found = 1
for n = 1, #pallist, 1 do
if db.valueInArray(pair,pallist[n]) == false then
plist[found] = pallist[n]; found = found + 1;
end
end
 
pair[pal_index] = plist -- ex: ["pal"]
 
return pair -- Is now a 2 color RAMP
end
--
 
-- Remove new col entry from ramp's pallist and add it to the ramp, returns an updated ramp
-- RampList = [1,2] ["pal"] = palList = [3,4,5], addindex = 3
-- --> [1,2,3] palList = [4,5]
function db.updateRamp(ramp,addindex,pal_index)
local n,found,pallist,plist,newramp
plist = {}
pallist = ramp[pal_index]
 
-- New palList without added color to IndexList
found = 1
for n = 1, #pallist, 1 do
if pallist[n] ~= addindex then
plist[found] = pallist[n]; found = found + 1;
end
end
 
newramp = db.newArrayInsertLast(ramplist,addindex)
newramp[pal_index] = plist
return rlist
end
 
--
-- Returns a list of all inital ramps from color pairs
--
-- Weeds out bad pairs, attaches remaining palette colors and the first rgb-vector
--
--
function db.initiateRampList(pairs,pallist,pal_index,vec_index,min,maxmult,rw,gw,bw)
local n,ramplist,newpairs,accept,dist,c1,c2,max,rD,gD,bD
ramplist = {}
max = min + (142 / math.sqrt(#pallist)) * maxmult -- min ex: 8-12
accept = 0
 
for n = 1, #pairs, 1 do
c1 = pallist[pairs[n][1]]
c2 = pallist[pairs[n][2]]
rD = c2[1] - c1[1]
gD = c2[2] - c1[2]
bD = c2[3] - c1[3]
dist = math.sqrt( (rw*rD)^2 + (gw*gD)^2 + (bw*bD)^2 )
 
if dist >= min and dist <= max then
accept = accept + 1; ramplist[accept] = db.initiateRamp(pairs[n],pallist,pal_index);
ramplist[accept][vec_index] = {rD, gD, bD, dist}; -- Add first color vector, ONLY KEEP DISTANCE?
end
end
 
return ramplist
end
 
 
function db.findRampExpansionColors(ramp)
local clist
clist = {}
-- Calculate vectors here?
return clist
end
 
 
function db.findRAMPS(min_len, max_len)
local i,n,c,pallist,ramp,ramplist,pairs,spairs,palindex,vecindex,found,donelist,newlist,dones
local colorlist
palindex = "pal"
vecindex = "vector"
pallist = db.fixPalette(db.makePalList(256), 0)
pairs = db.pairsFromList(db.makeIndexList(pallist,-1), 0)
ramplist = db.initiateRampList(pairs,pallist,palindex,vecindex, 8,0.75, 0.26,0.55,0.19)
 
-- MIN_LEN = 5
-- MAX_LEN = 10
 
-- Split Ramp-build into two parts:
-- 1. Build ramps >= MIN_LEN, NONE added to 'Done'
-- 2. Run til no more ramps can be expanded or reaches MAX_LEN, ALL ramps added to 'Done'
 
for i = 1, (min_len - 2), 1 do -- Assuming 2 for inital pairs (2 color ramps)
newlist = {}
found = 0
for n = 1, #ramplist, 1 do
ramp = ramplist[n]
colorlist = db.findRampExpansionColors(ramp) -- Colors that can split the current ramp into new expanded ramps
for c = 1, #colorlist, 1 do
found = found + 1; newlist[found] = db.updateRamp(ramp,colorlist[c],palindex); -- Ramp is expanded by 1 color
end
end
ramplist = newlist
end
 
 
donelist = {}; dones = 0
 
repeat
newlist = {}
found = 0
for n = 1, #ramplist, 1 do
ramp = ramplist[n]
if true == false then
found = found + 1; newlist[found] = db.updateRamp(ramp,color,palindex);
else
dones = dones + 1; donelist[dones] = ramp;
end
end
--ramplist = newlist
until found == 0
 
return #pairs.." - "..#ramplist
end
 
--
-- ... eof Misc. Logical Operations ...
--
 
 
-- ***************************************
-- *** General RGB-Color Modifications ***
-- ***************************************
 
 
--
function db.makeComplementaryColor(r,g,b,brikeeplev) -- Lev: 0 = Normal, 1 = Loose, 2 = Strict
 
local bri_o,bri_n,bdiff
 
function cap(v) return math.max(0,math.min(v,255)); end
 
bri_o = db.getBrightness(r,g,b)
r,g,b = db.shiftHUE(r,g,b,180)
 
if brikeeplev > 0 then
 
for n = 0, brikeeplev*3-1, 1 do -- Must iterate to reduce brightness error
bri_n = db.getBrightness(r,g,b)
bdiff = (bri_o - bri_n) / 2 * brikeeplev
r = cap(r + bdiff)
g = cap(g + bdiff)
b = cap(b + bdiff)
end
 
end
 
return r,g,b
 
end
--
 
 
-- *** Color balance ***
--
-- bri_flag: Preserve brightness
-- loose_flag: Loose preservation restrictions for brightness and balance
--
-- Jeez, was this a tricky sucker; color-balance is just adding and capping...
-- but trying color-balance with preserved perceptual brightness is a different monster...
-- ...so bad I could only solve it by iterative error correction.
--
function db.ColorBalance(r,g,b,rd,gd,bd,bri_flag,loose_flag) -- preserve brightness
local rw,gw,bw,ri,gi,bi,itot,rni,gni,bni,ro,go,bo,ovscale,lev,count,rt,gt,bt,rf,gf,bf,bri
 
-- Dawn 3.0, [0.26,0.55,0.19], 0-255 bri-colorscale adjust = 1.56905
rw,gw,bw = 0.26, 0.55, 0.19
 
function cap(v) return math.min(255,math.max(v,0)); end
bri = db.getBrightness(r,g,b)
 
 
-- Loose brightness & balance preservation, a good compromise.
if bri_flag == true and loose_flag == true then
 
lev = (rd + gd + bd) / 3
rd = rd - lev
gd = gd - lev
bd = bd - lev
 
brin = db.getBrightness(cap(r+rd),cap(g+gd),cap(b+bd))
itot = brin - bri
rd = rd - itot
gd = gd - itot
bd = bd - itot
 
end
 
 
if bri_flag == true and loose_flag == false then
 
itot = 255
count = 0
 
-- Normalize (Yup, it's right only to normalize once first..cont.norm. will have some counter-effect)
lev = (rd + gd + bd) / 3
rd = rd - lev
gd = gd - lev
bd = bd - lev
 
repeat
 
--messagebox("Norm:"..rd..", "..gd..", "..bd)
 
-- Calculate total brightness change
-- Note: Perceptual Brightness is exponential, and can't be delta-adjusted for anything other than greyscales.
-- Although the formula for the new brightness corrected normalization level can can be derived...
-- ...it doesn't do much good since the bigger problem is overflow outside the 0-255 boundary.
-- As for now, I see no other means to solve this issue than with iterative error-correction.
 
rt = r+rd
gt = g+gd
bt = b+bd
itot = 9e99
rni = rd
gni = gd
bni = bd
-- We can get brightness of negative values etc. So bri-correction is put on hold until values are scaled down
if (rt>=0 and gt>=0 and bt>=0) and (rt<256 and gt<256 and bt<256) then
brin = db.getBrightness(rt,gt,bt)
itot = brin - bri
--messagebox("Bri Diff: "..itot)
-- Brightness adjusted balance
rni = rd - itot
gni = gd - itot
bni = bd - itot
end
 
--messagebox("Bri Adj Bal:"..rni..", "..gni..", "..bni)
 
-- Apply balance to find overflow (as fraction of the channel change)
ro = math.max( math.max((r + rni)-255,0), math.abs(math.min((r + rni),0)) ) / math.max(math.abs(rni),1)
go = math.max( math.max((g + gni)-255,0), math.abs(math.min((g + gni),0)) ) / math.max(math.abs(gni),1)
bo = math.max( math.max((b + bni)-255,0), math.abs(math.min((b + bni),0)) ) / math.max(math.abs(bni),1)
 
ovscale = 1 - math.max(ro,go,bo)
 
-- Scaling balances might be logically incorrect (as they can be seen as constant differences)
-- But scaling DOWN is quite harmless and I don't see how it could be done otherwise...
-- ex: +10 red, +5 blue: Scale x2 = +20 red, +10 blue -> More red over blue than ordered, a contrast behaviour.
-- +10 red, +5 blue: Scale x0.5 = +5 red, +2.5 blue -> Less of everything, but a part of the order. Harmless?
--
rd = rni * ovscale
gd = gni * ovscale
bd = bni * ovscale
 
count = count + 1
 
--messagebox("Final bal:"..rd..", "..gd..", "..bd)
 
until math.abs(itot) < 1 or count > 5
 
end
 
rf = r + rd
gf = g + gd
bf = b + bd
 
--messagebox("Result color:"..rf..", "..gf..", "..bf)
 
return rf,gf,bf
end
--
 
 
 
--
-- bri_flag: Preserve brightness
-- cap_flag: Cap new color at 0-255, has a desaturating effect for large values.
--
function db.ColorBalanceXXX(r,g,b,rd,gd,bd,bri_flag,cap_flag) -- preserve brightness
local rf,gf,bf
 
if cap_flag == true then
rd = math.min(255,math.max(0, r+rd)) - r
gd = math.min(255,math.max(0, g+gd)) - g
bd = math.min(255,math.max(0, b+bd)) - b
end
 
local rw,gw,bw,ri,gi,bi,itot,rni,gni,bni,ro,go,bo,ovscale
 
 
-- Dawn 3.0, [0.26,0.55,0.19], 0-255 bri-colorscale adjust = 1.56905
rw,gw,bw = 0.26, 0.55, 0.19
 
if bri_flag == true then
 
-- Calculate total brightness change
--ri = rd * rw
--gi = gd * gw
--bi = bd * bw
--itot = math.sqrt(ri^2 + gi^2 + bi^2)
 
bri = db.getBrightness(r,g,b)
brin = db.getBrightness(r+rd,g+gd,b+bd)
itot = brin - bri
 
-- Normalized and Brightness adjusted balance
rni = rd - itot
gni = gd - itot
bni = bd - itot
 
-- Apply balance to find overflow (as fraction of the channel change)
ro = math.max( math.max((r + rni)-255,0), math.abs(math.min((r + rni),0)) ) / math.max(math.abs(rni),1)
go = math.max( math.max((g + gni)-255,0), math.abs(math.min((g + gni),0)) ) / math.max(math.abs(gni),1)
bo = math.max( math.max((b + bni)-255,0), math.abs(math.min((b + bni),0)) ) / math.max(math.abs(bni),1)
 
ovscale = 1 - math.max(ro,go,bo)
 
rd = rni * ovscale
gd = gni * ovscale
bd = bni * ovscale
 
end
 
rf = r + rd
gf = g + gd
bf = b + bd
 
return rf,gf,bf
end
--
 
--
function db.getContrast(ch) -- Channel, returns fraction -1..0..1, negative for ch < 127.5
--return math.abs((ch / 127.5) - 1)
return (ch / 127.5) - 1
end
--
 
--
function db.getAvgContrast(r,g,b)
return (math.abs(db.getContrast(r)) + math.abs(db.getContrast(g)) + math.abs(db.getContrast(b))) / 3
end
--
 
--
-- Mode = 0: Proportional - all colors reach max contrast at 100%
--
-- Mode = 1: Linear - percentage simply added
--
function db.changeContrastOLD(r,g,b,prc,mode)
 
local m,rd,gd,bd,rv,gv,bv,rc,gc,bc,base,sign
 
base = 1; sign = 1
if prc < 0 then base = 0; sign = -1; end -- decontrast
 
m = prc / 100 * sign
 
-- mode 0
rc = db.getContrast(r)
rd = (base - math.abs(rc)) * m * db.sign(rc)
rv = (rc+rd+1) * 127.5
 
gc = db.getContrast(g)
gd = (base - math.abs(gc)) * m * db.sign(gc)
gv = (gc+gd+1) * 127.5
 
bc = db.getContrast(b)
bd = (base - math.abs(bc)) * m * db.sign(bc)
bv = (bc+bd+1) * 127.5
 
return rv,gv,bv
 
end
--
 
function db.changeContrast(r,g,b,prc) -- Photoshop style
 
local m,rd,gd,bd,rv,gv,bv,rc,gc,bc
 
m = 1 + math.pow((255 / 100 * prc),3) / (255*255)
 
-- decontrast
if prc < 0 then
m = 1 - math.abs(prc)/100
end
rc = db.getContrast(r)
rd = rc * m
rv = (rd+1) * 127.5
 
gc = db.getContrast(g)
gd = gc * m
gv = (gd+1) * 127.5
 
bc = db.getContrast(b)
bd = bc * m
bv = (bd+1) * 127.5
 
return rv,gv,bv
 
end
 
 
 
--
function db.getBrightness(r,g,b) -- 0-255
local bri
--bri = (r+g+b)/3
--bri = r*0.3 + g*0.59 + b*0.11 -- Luma Y'601
--bri = math.sqrt((r*0.3)^2 + (g*0.59)^2 + (b*0.11)^2) -- Luma Y'601
--bri = r*0.245 + g*0.575 + b*0.18 -- Dawn 2.0
 
bri = math.sqrt((r*0.26)^2 + (g*0.55)^2 + (b*0.19)^2) * 1.56905 -- Dawn 3.0
return bri
end
--
 
 
--
-- Note on desaturation: These functions are all junk, the only way to desaturate
-- is to fade a color into it's corresponding greyscale.
--
 
--
function db.desaturate(percent,r,g,b) -- V1.0 by Richard Fhager
local a,p
p = percent / 100
a = (math.min(math.max(r,g,b),255) + math.max(math.min(r,g,b),0)) * 0.5 * p
r = r + (a-r*p) -- a+r*(1-p)
g = g + (a-g*p)
b = b + (a-b*p)
return r,g,b
end
--
 
--
function db.desaturateA(percent,c) -- array version
local r,g,b,a
r = c[1]
g = c[2]
b = c[3]
p = percent / 100
a = (math.min(math.max(r,g,b),255) + math.max(math.min(r,g,b),0)) * 0.5 * p
r = r + (a-r*p)
g = g + (a-g*p)
b = b + (a-b*p)
return {r,g,b}
end
--
 
--
function db.desatAVG(desat,c) -- Desaturation, simpe average
r = c[1]
g = c[2]
b = c[3]
p = desat / 100
a = (r+g+b)/3
r = r + p*(a-r)
g = g + p*(a-g)
b = b + p*(a-b)
return {r,g,b}
end
--
 
 
--
function db.getSaturation(r,g,b) -- HSL
local M,m,c,s,l
M = math.max(r,g,b)
m = math.min(r,g,b)
c = (M - m)/255
s = 0
if c ~= 0 then
--l = (0.3*r + 0.59*g + 0.11*b)/255 -- HSLuma: Y'601
l = (M+m)/510 -- This produces a quite "correct looking" divison of saturation
if l <= 0.5 then s = c / (2*l); end
if l > 0.5 then s = c / (2-2*l); end
end
return math.min(255,s * 255)
end
--
 
--
function db.getTrueSaturationX(r,g,b) -- Distance from grayscale axis. Not HSV/HSL
local sat,bri
bri = (r+g+b) / 3
sat = math.min(255, math.sqrt((r-bri)^2 + (g-bri)^2 + (b-bri)^2) * 1.224744875)
return sat
end
--
 
-- WIP. Trying to find a more natural model for estimating Saturation
-- Current: (HSL + True) / 2
function db.getAppSaturation(r,g,b)
return math.min(255, (db.getSaturation(r,g,b) + db.getTrueSaturationX(r,g,b)) / 2)
end
--
 
--
function db.saturate(percent,r,g,b)
local a,m,p,mc
a = (math.min(math.max(r,g,b),255) + math.max(math.min(r,g,b),0)) * 0.5
m = math.min(255-math.max(r,g,b), math.min(r,g,b))
p = percent * (m / 100)
mc = math.max((r-a),(g-a),(b-a)) -- Can this be derived elsewhere?
if mc ~= 0 then
r = r + (r-a) * p / mc
g = g + (g-a) * p / mc
b = b + (b-a) * p / mc
end
return r,g,b
end
--
 
--
-- Super Saturate: Better than Photoshop etc.
--
-- Higher than 100% power is ok
--
function db.saturateAdv(percent,r,g,b,brikeeplev,greydamp) -- brikeep = 0 - 2
local a,m,p,mc,bri_o,bri_n,bdiff,mx,mi,adj,q,n
function cap(v) return math.max(0,math.min(v,255)); end
mx = math.max(r,g,b)
mi = math.min(r,g,b)
bri_o = db.getBrightness(r,g,b)
a = (math.min(mx,255) + math.max(mi,0)) * 0.5
m = math.min(255-mx, mi)
p = percent * (m / 100)
mc = math.max((r-a),(g-a),(b-a)) -- Can this be derived elsewhere?
if mc ~= 0 and m ~= 0 then
adj = math.min(1,(mx - mi) / m) -- Reduce effect on low saturation
if greydamp == false then adj = 1; end
q = p / mc * adj
r = cap( r + (r-a) * q )
g = cap( g + (g-a) * q )
b = cap( b + (b-a) * q )
end
for n = 0, brikeeplev*2, 1 do -- Must iterate to reduce brightness error
bri_n = db.getBrightness(r,g,b)
bdiff = (bri_o - bri_n) / 2 * brikeeplev
r = cap(r + bdiff)
g = cap(g + bdiff)
b = cap(b + bdiff)
end
return r,g,b
end
--
 
 
--
-- Lightness: Darken / Brighten color (Argument and returnvalue is a rgb-list)
-- Rate of change is inversely proportional to the distance of the max/min.
-- i.e. all colors/channels will reach max/min at the same time (at 0 or 100 %)
-- (As opposed to 'Brightness' where all channels are changed by a constant value)
--
function db.lightness(percent,c)
local v,r,g,b,p
r = c[1]
g = c[2]
b = c[3]
p = math.abs(percent/100)
v = 255
if percent < 0 then v = 0; end
r = r + (v - r)*p
g = g + (v - g)*p
b = b + (v - b)*p
return {r,g,b}
end
--
 
--
function db.changeLightness(r,g,b,percent)
local v
v = db.lightness(percent,{r,g,b})
return v[1],v[2],v[3]
end
--
 
--
function db.getLightness(r,g,b) -- HSL bi-hexcone
return (math.max(r,g,b) + math.min(r,g,b)) / 2
end
--
 
--
function db.shiftHUE(r,g,b,deg) -- V1.3 R.Fhager 2007, (Heavily derived code, hehe...)
local c,h,mi,mx,d,s,p,i,f,q,t
c = {g,b,r}
mi = math.min(r,g,b)
mx = math.max(r,g,b); v = mx;
d = mx - mi;
s = 0; if mx ~= 0 then s = d/mx; end
p = 1; if g ~= mx then p = 2; if b ~= mx then p = 0; end; end
if s~=0 then
h=(deg/60+(6+p*2+(c[1+p]-c[1+(p+1)%3])/d))%6;
i=math.floor(h);
f=h-i;
p=v*(1-s);
q=v*(1-s*f);
t=v*(1-s*(1-f));
c={v,q,p,p,t,v}
r = c[1+i]
g = c[1+(i+4)%6]
b = c[1+(i+2)%6]
end
 
return r,g,b
end
--
 
--
function db.getHUE(r,g,b,greytol) -- 0-6 (6.5 = Greyscale), mult. with 60 for degrees
-- 1 Color diff is roughly detected by Tolerance = 0.0078125 (Tol. incr. with lightness etc.)
local c,h,mi,mx,d,s,p,i,f,q,t
c = {g,b,r}
mi = math.min(r,g,b)
mx = math.max(r,g,b); v = mx;
d = mx - mi;
s = 0; if mx ~= 0 then s = d/mx; end
p = 1; if g ~= mx then p = 2; if b ~= mx then p = 0; end; end
 
h = 6.5 -- for custom graphical purposes
if s>greytol then -- can't use >=
h=(6+p*2+(c[1+p]-c[1+(p+1)%3])/d)%6;
end
 
return h
end
--
 
--
-- ... eof RGB color modifications ...
--
 
 
 
-- ****************************************
-- *** Custom Color / Palette functions ***
-- ****************************************
 
 
--# of Unique colors in palette:
--#db.fixPalette(db.makePalList(256))
 
--# of Colors in Image:
--#db.makePalListFromHistogram(db.makeHistogram())
 
--# of Unique colors in Image:
--#db.fixPalette(db.makePalListFromHistogram(db.makeHistogram()))
 
--
function db.rgbcap(r,g,b,mx,mi)
local m = math
return m.max(mi,m.min(r,mx)), m.max(mi,m.min(g,mx)), m.max(mi,m.min(b,mx))
end
--
 
--
function db.rgbcapInt(r,g,b,mx,mi)
local m = math
return m.floor(m.max(mi,m.min(r,mx))), m.floor(m.max(mi,m.min(g,mx))), m.floor(m.max(mi,m.min(b,mx)))
end
--
 
 
--
function db.makePalList(cols)
local pal,n,r,g,b
pal = {}
for n = 0, cols-1, 1 do
r,g,b = getcolor(n)
pal[n+1] = {r,g,b,n}
end
return pal
end
--
 
--
function db.makeSparePalList(cols)
local pal,n,r,g,b
pal = {}
for n = 0, cols-1, 1 do
r,g,b = getsparecolor(n)
pal[n+1] = {r,g,b,n}
end
return pal
end
--
 
 
--
-- Use to remove the black colors (marks unused colors) from palette-list
-- if it's known that no black color exists in the image.
function db.stripBlackFromPalList(pallist)
local i,u,c,dummy; i = 257 -- Do 'nothing' If using a full 256 col palette with no blacks
for u = 1, #pallist, 1 do
c = pallist[u]
if (c[1]+c[2]+c[3]) == 0 then i = u; end
end
dummy = table.remove(pallist,i)
return pallist
end
--
 
--
function db.stripIndexFromPalList(pallist,colindex)
local i,u,c,dummy
for u = 1, #pallist, 1 do
c = pallist[u]
if c[4] == colindex then i = u; end
end
dummy = table.remove(pallist,i)
return pallist
end
--
 
--
function db.addHSBtoPalette(pallist)
local n,hue,sat,rgb
for n=1, #pallist, 1 do
rgb = pallist[n]
pallist[n][5] = db.getHUE(rgb[1],rgb[2],rgb[3],0)
pallist[n][6] = db.getSaturation(rgb[1],rgb[2],rgb[3])
pallist[n][7] = db.getBrightness(rgb[1],rgb[2],rgb[3])
end
return pallist -- {r,g,b,n,bri,hue,sat}
end
--
 
--
function db.makePalListRange(start,ends)
local pal,n,r,g,b,a
pal = {}
a = 1
for n = start, ends, 1 do
r,g,b = getcolor(n)
pal[a] = {r,g,b,n}; a = a + 1;
end
return pal
end
--
 
 
--
function db.makePalListShade(cols,sha) -- Convert colors to less bits, colorcube operations etc.
local pal,n,r,g,b,mf,div
mf = math.floor
div = 256 / sha
pal = {}
for n = 0, cols-1, 1 do
r,g,b = getcolor(n)
pal[n+1] = {mf(r/div),mf(g/div),mf(b/div),n}
end
return pal
end
--
--
function db.makePalListShadeSPARE(cols,sha) -- Convert colors to less bits, colorcube operations etc.
local pal,n,r,g,b,mf,div
mf = math.floor
div = 256 / sha
pal = {}
for n = 0, cols-1, 1 do
r,g,b = getsparecolor(n)
pal[n+1] = {mf(r/div),mf(g/div),mf(b/div),n}
end
return pal
end
--
 
 
 
--
function db.getColorDistance_weight(r1,g1,b1,r2,g2,b2,rw,gw,bw)
return math.sqrt( (rw*(r1-r2))^2 + (gw*(g1-g2))^2 + (bw*(b1-b2))^2 )
end
--
 
--
-- Since brightness is exponential, each channel may work as a "star" drowning the color
-- of a lesser channel. This algorithm is an approximation to adjust distances for this phenomenon.
-- Ex: Adding 32 red to black is visually obvious, but adding 64 red to full green is almost
-- impossible to detect by the naked eye.
--
-- However this isn't a complete solution so we may weigh in brightness as well...
--
-- If cv = 0 (0..1) then prox acts as ordinary perceptual colordistance
-- if bri = 1 (0..1) then distance is only that of brightness
function db.getColorDistanceProx(r1,g1,b1,r2,g2,b2,rw,gw,bw,normalizer, cv,briweight)
local rp1,gp1,bp1,rp2,gp2,bp2,v,m1,m2,prox,bdiff; v = 2*255*255
m1 = math.max(r1,g1,b1)
m2 = math.max(r2,g2,b2)
rp1 = 1 - math.sqrt((r1-m1)^2 / v) * cv
gp1 = 1 - math.sqrt((g1-m1)^2 / v) * cv
bp1 = 1 - math.sqrt((b1-m1)^2 / v) * cv
 
rp2 = 1 - math.sqrt((r2-m2)^2 / v) * cv
gp2 = 1 - math.sqrt((g2-m2)^2 / v) * cv
bp2 = 1 - math.sqrt((b2-m2)^2 / v) * cv
 
bdiff = math.abs(db.getBrightness(r1,g1,b1) - db.getBrightness(r2,g2,b2)) -- weights are hardcoded in function
prox = math.sqrt( (rw*(r1*rp1-r2*rp2))^2 + (gw*(g1*gp1-g2*gp2))^2 + (bw*(b1*bp1-b2*bp2))^2 ) * normalizer
 
return prox * (1-briweight) + bdiff * briweight
end
--
 
--
function db.getBestPalMatch(r,g,b,pal,index_flag) -- pal = [r,g,b,palindex], index_flag -> return palindex if pal is sorted or reduced
local diff,best,bestcol,cols,n,c,p
cols = #pal
bestcol = -1
best = 9e99
 
for n=1, cols, 1 do
p = pal[n]
diff = db.getColorDistance_weight(r,g,b,p[1],p[2],p[3],0.26,0.55,0.19) * 1.569
if diff < best then bestcol = n; best = diff; end
end
 
if index_flag == true then
bestcol = pal[bestcol][4] + 1
end
 
return bestcol-1 -- palList index start at 1, image-palette at 0
end
--
 
 
-- Normally this function will return the (image)palette index of best color
-- ...but if the palette has been sorted with 'fixPalette' it will return the index
-- of the custom palList, setting index_flag will convert this value to image-palette index
--
-- HYBRID means the colormatch is a combo of color and (perceptual)brightness
--
--
function db.getBestPalMatchHYBRID(rgb,pal,briweight,index_flag) -- Now correctly balanced
local diff,diffC,diffB,best,bestcol,cols,n,c,r,g,b,p,obri,pbri
cols = #pal
bestcol = -1
best = 9e99
 
--messagebox(briweight)
 
-- Note: Not secured against negative values (this algorithm is SLOW, we cannot afford it)
r = rgb[1]
g = rgb[2]
b = rgb[3]
 
obri = db.getBrightness(r,g,b) -- 0-255
 
for n=1, cols, 1 do
p = pal[n]
pbri = db.getBrightness(p[1],p[2],p[3])
diffB = math.abs(obri - pbri)
-- we need to normalize the distance by the weights
diffC = db.getColorDistance_weight(r,g,b,p[1],p[2],p[3],0.26,0.55,0.19) * 1.569
 
diff = briweight * (diffB - diffC) + diffC
if diff < best then bestcol = n; best = diff; end
end
 
if index_flag == true then
bestcol = pal[bestcol][4] + 1 -- Since we detract 1 on return, God Lua is stupid
end
 
return bestcol-1 -- palList index start at 1, image-palette at 0
end
--
 
 
 
--
-- Special version of Hybrid-remapping for mixPalette list
--
-- mixpal: {score,col#1,col#2,dist,rm,gm,bm, c1_r,c1_g,c1_b, c2_r,c2_g,c2_b}
--
-- returns: {col#1,col#2} (index of palette)
--
function db.getBestPalMatchHybridMIX(rgb,mixpal,briweight,mixreduction)
local diff,diffC,diffB,best,bestcol,cols,n,c,r,g,b,p,obri,pbri, distmult
cols = #mixpal
bestcol = -1
best = 9e99
 
-- We will simply add the the distance to the mix with the distance between the mixcolors and
-- employ a user tolerance to much the latter will matter.
--distmult = 255 / 9.56 / 100 * mixreduction -- 16 shades
distmult = 1.56902 / 100 * mixreduction -- 24-bit, Dawn3.0 colormodel
 
-- Note: Not secured against negative values (this algorithm is SLOW, we cannot afford it)
r = rgb[1]
g = rgb[2]
b = rgb[3]
 
obri = db.getBrightness(r,g,b) -- 0-255
 
for n=1, cols, 1 do
p = mixpal[n]
--pbri = db.getBrightness(p[5],p[6],p[7])
 
-- *** DawnBringer's exponetial color brightness dither resolution phenomena theorem ***
-- Bri = color value ^ 2
-- Two adjacent pixels displayed with "normal high resolution" will NOT have the perceptual
-- brightness of the resulting mixcolor. The brightness lies closer to that of the brightest pixel.
-- Bri[(C1+C2)/2] = SQRT( (C1bri^2 + C2bri^2) / 2 )
-- (Brightness according to Dawn-model: bri = SQRT( (r*.26)^2 + (g*.55)^2 + (b*.19)^2 ) )
 
pbri = math.sqrt((db.getBrightness(p[8],p[9],p[10])^2 + db.getBrightness(p[11],p[12],p[13])^2) / 2)
 
diffB = math.abs(obri - pbri)
-- we need to normalize the distance by the weights
diffC = db.getColorDistance_weight(r,g,b,p[5],p[6],p[7],0.26,0.55,0.19) * 1.569 + p[4]*distmult
 
diff = briweight * (diffB - diffC) + diffC
if diff <= best then bestcol = n; best = diff; end
end
 
return {mixpal[bestcol][2], mixpal[bestcol][3]}
--return {mixpal[bestcol][2], 0}
 
 
 
end
--
 
 
 
--
function db.matchcolorHSB(h,s,b,pallist,index_flag)
--
-- why don't we just convert HSB-diagram to RGB and do normal colormatching?
-- Not the same...
--
local n,c,best,bestcol,pb,ph,ps,diff,huediff,huecorr,hue_adj,sat_adj,bri_adj
bestcol = -1
best = 9e99
-- higher adjust means more impact (higher hue gives more interpolation )
hue_adj = 4
sat_adj = 0.075
bri_adj = 2
 
huecorr = 255 / 6 -- Our Hue goes from 0.0 - 5.999
 
for n=1, #pallist, 1 do
c = pallist[n]
ph = c[5]
ps = c[6]
pb = c[7]
 
huediff = math.abs(h-ph*huecorr)
if huediff > 127 then huediff = huediff - (huediff % 127) * 2; end
 
--if ph == 6.5 then huediff = 0; end
 
-- With less saturation, exact hue becomes less important and brightness more usefull
-- This allows for greyscales and low saturation colors to work smoothly.
huediff = huediff * (ps /255)
 
diff = hue_adj*huediff^2 + (s-ps)^2 * sat_adj + (b-pb)^2 * bri_adj
if diff <= best then bestcol = n; best = diff; end
end
 
if index_flag == true then
bestcol = pallist[bestcol][4] + 1 -- Since we detract 1 on return, God Lua is stupid
end
 
return bestcol-1
 
end
--
 
--
-- Used by PaletteAnalysis.lua, FindRamps(), MixColors() etc.
-- Assigns is used by ApplySpare script
--
function db.fixPalette(pal,sortflag) -- Arrange palette & only keep unique colors
 
local n,l,rgb,i,unique,bri,hue,sat,ulist,indexpal,newpal,dtot
ulist = {}
indexpal = {}
newpal = {}
local doubles,assign
doubles = {}; assign = {}
 
l = #pal
 
unique = 1 -- ok, see how stupid lua is
dtot = 0
for n=1, l, 1 do
rgb = pal[n]; -- actually rgbn
i = 1 + rgb[1] * 65536 + rgb[2] * 256 + rgb[3];
bri = db.getBrightness(rgb[1],rgb[2],rgb[3])
if indexpal[i] == nil then
indexpal[i] = rgb; ulist[unique] = {i,bri}; unique = unique+1;
assign[rgb[4]+1] = rgb[4] -- really n, but can we be sure?
else
doubles[rgb[4]] = true; -- Mark as double (This is wrong; starts at 0...but col 0 cannot be a double so...)
dtot = dtot + 1
assign[rgb[4]+1] = indexpal[i][4] -- Reassign removed color
end
end
 
-- sort ulist
if sortflag == 1 then db.sorti(ulist,2); end -- sort by brightness
 
l = #ulist
for n=1, l, 1 do
newpal[n] = indexpal[ulist[n][1]]
end
 
newpal["assigns"] = assign -- Complete list of image color assigns (removed cols will point to 1st occurence)
newpal["doubles"] = doubles
newpal.double_total = dtot
 
--messagebox("unique colors", unique-1)
 
return newpal
 
end
--
 
--
function db.drawColorspace12bit(x,y,cols,size)
local r,g,b,c,rows,row,col,s16,rx,ry,xx,yy
s16 = size*16
rows = math.floor(16/cols)
 
for g = 0, 15, 1 do
col = g % cols
row = math.floor(g / cols)
for r = 0, 15, 1 do
for b = 0, 15, 1 do
c = matchcolor(r*17,g*17,b*17)
xx = x+col*s16+r*size
yy = y+row*s16+b*size
for ry = 0, size-1, 1 do
for rx = 0, size-1, 1 do
putpicturepixel(xx+rx,yy+ry,c)
end;end
end
end
end
end
--
 
--
function db.drawHSBdiagram(pallist,posx,posy,width,height,size,sat)
--db.addHSBtoPalette(palList)
local x,y,c
for y = 0, height-1, 1 do
for x = 0, width-1, 1 do
hue = 255/width * x
bri = 255/height * y
c = db.matchcolorHSB(hue,sat,bri,pallist,true)
db.drawRectangle(posx + x*size, posy + y*size,size,size, c)
end
end
end
--
 
--
function db.polarHSBdiagram(ox,oy,radius,pol,brilev,huelev,saturation,dark2bright_flag)
 
local pal,bstep,bstep2,hstep,hstep2,bri,hue,sx,sy,cx,cy,x,y,p1,p2,c
 
pal = db.addHSBtoPalette(db.fixPalette(db.makePalList(256)))
 
bstep = radius / (brilev + pol)
bstep2 = bstep / 2
hstep = -360 / huelev
hstep2 = hstep / 2
 
c = 255; if dark2bright_flag then c = 0; end
drawdisk(ox,oy,math.ceil(pol*bstep),matchcolor(c,c,c))
 
for y=pol, brilev+pol-1,1 do
bri = (brilev - y + pol) * (256 / brilev)
 
if dark2bright_flag then
bri = (brilev - (brilev - y + pol)) * (256 / brilev)
end
 
for x=0, huelev-1,1 do
 
hue = x * (360 / huelev) * 255/360
 
c = db.matchcolorHSB(hue,saturation,bri,pal,true)
 
sx = ox
sy = oy - y*bstep
 
cx,cy = db.rotationFrac(x*hstep,ox,oy,sx,sy)
 
x1,y1 = db.rotation(x*hstep-hstep2,ox,oy,ox, sy-bstep2)
x2,y2 = db.rotation(x*hstep+hstep2,ox,oy,ox, sy-bstep2)
x3,y3 = db.rotation(x*hstep-hstep2,ox,oy,ox, sy+bstep2)
x4,y4 = db.rotation(x*hstep+hstep2,ox,oy,ox, sy+bstep2)
 
p1 = {{x1,y1},{x2,y2},{x3,y3}}
p2 = {{x3,y3},{x4,y4},{x2,y2}}
 
db.fillTriangle(p1,c,0,true,false) -- triangle, fillcol, linecol, fill, wire
db.fillTriangle(p2,c,0,true,false)
 
end
updatescreen(); if (waitbreak(0)==1) then return; end
end
 
end -- polarHSB
--
 
 
--
-- Histograms, remapping etc.
--
 
--
function db.makeHistogram()
local n,y,x,c,w,h,list; list = {}
w, h = getpicturesize()
for n = 1, 256, 1 do list[n] = 0; end
for y = 0, h - 1, 1 do
for x = 0, w - 1, 1 do
c = getpicturepixel(x,y)
list[c+1] = list[c+1] + 1
end
end
return list
end
--
 
--
function db.makeHistogramIndexed() -- With color index so it can be sorted etc.
local n,y,x,c,w,h,r,g,b,list; list = {}
w, h = getpicturesize()
for n = 1, 256, 1 do
r,g,b = getcolor(n-1)
list[n] = {0,n-1,r,g,b};
end
for y = 0, h - 1, 1 do
for x = 0, w - 1, 1 do
c = getpicturepixel(x,y)
list[c+1][1] = list[c+1][1] + 1
end
end
return list
end
--
 
--
function db.makeSpareHistogram()
local n,y,x,c,w,h,list; list = {}
w, h = getsparepicturesize()
--w,h = 512,360
for n = 1, 256, 1 do list[n] = 0; end
for y = 0, h - 1, 1 do
for x = 0, w - 1, 1 do
c = getsparepicturepixel(x,y)
list[c+1] = list[c+1] + 1
end
end
return list
end
--
 
 
--
-- Makes a palette-list from only the colors (histogram) that occurs in the image
-- Assumes image/palette has not changed since histogram was created
function db.makePalListFromHistogram(hist)
local n,r,g,b,list,count
list = {}
count = 1
for n = 1, #hist, 1 do
if hist[n] > 0 then
r,g,b = getcolor(n-1)
list[count] = {r,g,b,n-1}
count = count + 1
end
end
return list
end
--
 
function db.makePalListFromSpareHistogram(hist)
local n,r,g,b,list,count
list = {}
count = 1
for n = 1, #hist, 1 do
if hist[n] > 0 then
r,g,b = getsparecolor(n-1)
list[count] = {r,g,b,n-1}
count = count + 1
end
end
return list
end
--
 
 
--
function db.remap(org) -- Working with a remap-list there's no need of reading backuppixel
--messagebox("Remapping")
local x,y,c,i,w,h,s,f,col
f = getpicturepixel
s = false
w, h = getpicturesize()
for y = 0, h - 1, 1 do
for x = 0, w - 1, 1 do
c = f(x,y)
i = org[c+1]
if i == null then i = matchcolor(getbackupcolor(getbackuppixel(x,y))); s = true; col = c; end -- Find color for a removed double
putpicturepixel(x,y,i)
end
end
if s then messagebox("Remapping: Not all image colors were found in remap-list (re-assign), probably due to duplicate removal. Matchcolor was used, ex: col# "..col);
end
end
--
 
--
-- Same as db.remap but no comments
--
function db.remapImage(colassignlist) -- assignment list is optional
local x,y,c,w,i,h,assign
assign = false
if colassignlist ~= null then assign = true; end
w,h = getpicturesize()
for y = 0, h-1, 1 do
for x = 0, w-1, 1 do
c = getbackuppixel(x,y)
i = null; if assign then i = colassignlist[c+1]; end
if not assign or i == null then
i = matchcolor(getbackupcolor(c))
end
putpicturepixel(x,y,i)
end
end
end
--
 
--
-- Palette DeCluster: Color-reduction by fusing similar colors into new ones, using a desired tolerance.
-- This is a method similar to Median-Cut, but more surgical.
--
-- pallist: Palette list {r,g,b,palette_index}
-- hist: Histogram {color 0 pixels, color 1 pixels...etc} always a full 256 color list
-- crad: Cluster radius treshold in % of distance between black & white
-- A value of 0 will only remove identical colors
-- A value of 3-4 will usally fuse redundant colors without causing notice
-- prot_pow: (0..10) Protect common colors in histogram. Distances are increased by ocurrence.
-- Also gives protection to fused colors even if not using histogram (combined nominal weights)
-- pixels: Pixels in image (so protection can be calculated)
-- rw,gw,bw: Color weights (rw+gw+bw = 1, 0.33,0.33,0.33 is nominal)
--
-- Returns:
-- a new (c)palette list {r,g,b,{original palette_indices},fused flag, histogram_weight}
-- a remap list (org) [image color + 1] = remap color (in the new palette)
function db.deCluster(pallist, hist, crad, prot_pow, pixels, rw,gw,bw)
 
--messagebox(pixels)
 
local u,c,a,i,o,j,n,c1,c2,r,g,b,r1,g1,b1,r2,g2,b2,wt,rt,gt,bt,tot,pd
local worst,wtot,maxdist,maxDist,distfrac,clusterExists,clustVal,count,crad1
local cList,cPalList,clusterList,fuseCol,orgcols,newPalList,org
 
maxdist = math.sqrt(rw*rw*65025 + gw*gw*65025 + bw*bw*65025)
distfrac = 100 / maxdist
 
-- Let's just make a slightly more suitable format of the pallist (List for original color(s))
cPalList = {}
for u = 1, #pallist, 1 do
c = pallist[u]
cPalList[u] = {c[1],c[2],c[3],{c[4]},false,hist[c[4]+1]} -- r,g,b,{original colors},fuse_marker,histogram_weight
end
 
--table.insert(cPalList,{255,255,0,{257},false,1})
 
clusterExists = true
while clusterExists do
clusterExists = false
clusterList = {}
 
crad1 = crad + 1 -- avoid divison by zero
worst = 9999
for a = 1, #cPalList, 1 do
c1 = cPalList[a]
r1,g1,b1 = c1[1],c1[2],c1[3]
wtot = c1[6]
cList = {a}
maxDist = 0
for b = 1, #cPalList, 1 do
if (b ~= a) then
c2 = cPalList[b]
r2,g2,b2 = c2[1],c2[2],c2[3]
wt = c2[6]
pd = math.pow((1 + wt / pixels), prot_pow) -- Protection, increase distance
dist = db.getColorDistance_weight(r1,g1,b1,r2,g2,b2,rw,gw,bw) * distfrac * pd
if dist <= crad then
wtot = wtot + wt
table.insert(cList,b)
maxDist = math.max(dist,maxDist)
end
end
end -- b
if #cList > 1 then
clustVal = maxDist / (crad1 * #cList) * (wtot / #cList)
if clustVal < worst then
worst = clustVal
clusterList = cList
end
end
end -- a
--t = db.ary2txt(clusterList)
--messagebox("Worst cluster is "..t)
-- Fuse
if #clusterList > 1 then
clusterExists = true -- Run another iteration and look for more clusters
fuseCol = {0,0,0,{}}
rt,gt,bt,tot = 0,0,0,0
for n = 1, #clusterList, 1 do
i = clusterList[n]
c = cPalList[i]
--o = c[4][1] -- Original color (always #1 in list since fused colors can't re-fuse)
o = c[4] -- Original color list
--if c[5] == true then messagebox("Re-Fusing..."); end
r,g,b = c[1],c[2],c[3]
--wt = hist[o+1] -- Org. colors are 0-255
wt = c[6]
rt = rt + r * wt
gt = gt + g * wt
bt = bt + b * wt
tot = tot + wt
cPalList[i] = -1 -- Erase color
--table.insert(fuseCol[4],o)
orgcols = fuseCol[4]
for j = 1, #o, 1 do
table.insert(orgcols,o[j])
end
fuseCol[4] = orgcols
end
 
rt = rt / tot
gt = gt / tot
bt = bt / tot
fuseCol[1] = rt
fuseCol[2] = gt
fuseCol[3] = bt
fuseCol[5] = true -- fusecol marker
fuseCol[6] = tot
table.insert(cPalList,fuseCol)
--messagebox(#clusterList.." Colors was fused, resulting in "..rt..", "..gt..", "..bt)
newPalList = {}
for n = 1, #cPalList, 1 do
if cPalList[n] ~= -1 then
table.insert(newPalList,cPalList[n])
--newPalList = db.newArrayInsertLast(newPalList,cPalList[n])
end
end
cPalList = newPalList
--messagebox("Pal length: "..#cPalList)
statusmessage("DC - Image colors: "..#cPalList.." "); waitbreak(0)
end -- fuse
 
end -- while
 
-- Create remap-list
org = {}
count = 0
for u = 1, #cPalList, 1 do
c = cPalList[u]
for n = 1, #c[4], 1 do
i = c[4][n]
org[i+1] = count -- quick way to remap without matchcolor
end
count = count + 1
end
 
return org,cPalList
 
end; -- decluster
 
 
 
-- ------------- MEDIAN CUT V1.0 ------------
--
-- 256 color Palette Lua-version (converted from Evalion JS-script)
--
-- by Richard 'DawnBringer' Fhager
--
--
-- pal: [[r,g,b,i]] Pallist
-- cnum: Target number of colors in reduced palette
-- (step:) 1.. Pixel picks for processing, 1 = all pixels in image, best and slowest. 2 = 25% of pixels
-- qual: Flag Qualitative color selection (Normal mode)
-- quant: Flag Quantative color/pixel selection (Histogram) 100% mean that it count as much as quality
-- (One of or both qual/quant must be selected)
-- rgbw: [3] RGB-weights []. Weigh the color channels. ex: [1,1.333,0.75]
-- bits: 1-8 Bits used for each color channel in palette
-- quantpow: 0..1
--
-- return: A palette! A list of [r,g,b] values
--
-- NOTE: Quantity will act as a counterforce to altered colorspace (weights)...
-- Ex: if Green is considered bigger, it will be split into more blocks
-- but each blocks will have less colors and thus less quantity.
--
-- Perceptual colorspace (rgb-weights) will generally produce the best quality of palettes, but if
-- It's desirable to preserve stronger colors, esp. in small palettes,
-- it can be good to just use nominal space: 1,1,1
--
-- Histogram may be useful to assign more colors to an object that already covers most of the image,
-- however; if the object of interest is small in relation to a large (unimportant) background, it's
-- usually best not to have any histogram at all. Histogram will dampen strong infrequent colors.
 
 
function db.medianCut(pal,cnum,qual,quant,rgbw,bits,quantpow)
local n,x,y,xs,ys,rgb,blocklist,blocks
local len,res,chan,diff,maxdiff,maxblock,split
local qualnorm, quantnorm
 
-- Normalize 256 for quality/quantity relationship
qualnorm = 1 / math.sqrt(rgbw[1]^2 + rgbw[2]^2 + rgbw[3]^2)
quantnorm = 256 / #pal
 
blocklist = {}
blocklist[1] = {}; blocks = 1
 
for n=1, #pal, 1 do
blocklist[1][n] = pal[n];
end
 
analyzeBlock(blocklist[1],qual,quant,rgbw,qualnorm,quantnorm,quantpow)
 
failsafe = 0
while (blocks < cnum and failsafe < 256) do
failsafe = failsafe + 1
maxdiff = -1
maxblock = -1
for n=1, blocks, 1 do
diff = blocklist[n].diff
if (diff > maxdiff) then maxdiff = diff; maxblock = n; end -- maxchan is stored as .chan in block
end
split = splitBlock(blocklist,maxblock,qual,quant,rgbw,qualnorm,quantnorm,quantpow)
--if (split == false){ alert("Only found " + blocks + " (24-bit) colors!"); break; }
blocks = #blocklist
--status.value = "MC: " +blocks
end -- while
 
return blocks2Palette(blocklist,bits)
 
end
--
 
--
function blocks2Palette(blocklist,bits)
local n,r,g,b,c,pal,block,rgb,blen,M,dB,cB,rf,gf,bf
M = math
pal = {}
 
--bits = 1
dB = M.pow(2,8-bits)
cB = M.ceil(255 / (M.pow(2,bits) - 1))
 
for n=1, #blocklist, 1 do
block = blocklist[n]
r,g,b = 0,0,0
blen = #block
for c=1, blen, 1 do
rgb = block[c]
r = r + rgb[1]
g = g + rgb[2]
b = b + rgb[3]
end
 
rf = M.floor(M.min(255,M.max(0,M.floor(r/blen))) / dB) * cB
gf = M.floor(M.min(255,M.max(0,M.floor(g/blen))) / dB) * cB
bf = M.floor(M.min(255,M.max(0,M.floor(b/blen))) / dB) * cB
 
pal[n] = {rf, gf, bf, 0} -- col is avg. of all colors in block (index is set (to 0) for compatibility)
end -- blocklist
 
return pal
end
--
 
--
function analyzeBlock(block,qual,quant,rgbw,qualnorm,quantnorm,quantpow)
local r,g,b,n,rmin,gmin,bmin,rmax,gmax,bmax,rdif,gdif,bdif,chan,d,median,diff
local len,Mm,Mx,rgb,kv,qu
Mx,Mm = math.max, math.min
len = #block
 
rmin,gmin,bmin = 255,255,255
rmax,gmax,bmax = 0,0,0
 
for n=1, len, 1 do
rgb = block[n]
r = rgb[1] * rgbw[1]
g = rgb[2] * rgbw[2]
b = rgb[3] * rgbw[3]
--if (!isNaN(r) and !isNaN(g) and !isNaN(b)) then -- Ignore any erroneous data
rmin = Mm(rmin,r)
gmin = Mm(gmin,g)
bmin = Mm(bmin,b)
rmax = Mx(rmax,r)
gmax = Mx(gmax,g)
bmax = Mx(bmax,b)
--end
end
rdif = (rmax - rmin) -- * rgbw[1]
gdif = (gmax - gmin) -- * rgbw[2]
bdif = (bmax - bmin) -- * rgbw[3]
 
d = {{rmin,rdif,rmax},{gmin,gdif,gmax},{bmin,bdif,bmax}}
 
chan = 1 -- Widest channel
if (gdif > rdif) then chan = 2; end
if (bdif > rdif and bdif > gdif) then chan = 3; end
-- Ok, this is the average of the max/min value rather than an actual median
-- I guess this will fill the colorspace more uniformly and perhaps select extremes to a greater extent?
-- Which is better?
--median = d[chan][1] + d[chan][2] / 2 -- OLD same as median with nominal weights
median = (d[chan][1] + d[chan][3]) / 2
 
-- quantity and quality are normalized to 256 (256 is the total of colors in the set for quantity)
-- Note that, regardless of forumla, quality (distance) must always be greater in any block than quantity (colors/pixels)
-- Coz a block may contain many of only 1 unique color, thus rendering it impossible to split if selected.
kv = 1
qu = 1
if (quant) then kv = 1 + len*quantnorm*quantpow; end
if (qual) then qu = d[chan][2] * qualnorm; end
diff = qu + qu*kv^2.5
 
block.chan = chan
block.diff = diff
block.median = median
 
return {chan,diff,median,len}
 
end
--
 
function splitBlock(blocklist,maxblock,qual,quant,rgbw,qualnorm,quantnorm,quantpow)
local n,cmax,median,blockA,blockB,len,cB,block,rgb,res
blockA,blockB = {},{}
block = blocklist[maxblock]
 
res = true
 
chan = block.chan
median = block.median
 
cB = blocklist[maxblock] -- maxblock starts at 1 when called so it should not hava a +1
len = #cB
 
for n=1, len, 1 do
rgb = cB[n]
--if (rgb[chan] >= median) then blockA.push(rgb); end
--if (rgb[chan] < median) then blockB.push(rgb); end
if (rgb[chan]*rgbw[chan] >= median) then table.insert(blockA,rgb); end
if (rgb[chan]*rgbw[chan] < median) then table.insert(blockB,rgb); end
end
 
blocklist[maxblock] = blockA -- Can't be empty right?
analyzeBlock(blocklist[maxblock],qual,quant,rgbw,qualnorm,quantnorm,quantpow)
 
if (#blockB > 0) then
table.insert(blocklist,blockB)
analyzeBlock(blocklist[#blocklist],qual,quant,rgbw,qualnorm,quantnorm,quantpow) -- no -1 on blocklist
else
res = false
end
 
return res -- false = no split
end
 
------------ eof MEDIAN CUT --------------------------
 
 
-- ------------- MEDIAN REDUX V1.0 ------------
--
-- Divide space by greatest distance of any two colors (rather than MC-method of any given channel)
-- Basically it allows colorspace to be sliced at any angles rather than the "boxing" of MC.
--
--
-- by Richard 'DawnBringer' Fhager
--
--
-- pal: [[r,g,b,i,h]] Pallist (h = histogram/pixelcount)
-- cnum: Target number of colors in reduced palette
-- (step:) 1.. Pixel picks for processing, 1 = all pixels in image, best and slowest. 2 = 25% of pixels
-- qual: Flag Qualitative color selection (Normal mode)
-- quant: Flag Quantative color/pixel selection (Histogram) 100% mean that it count as much as quality
-- (One of or both qual/quant must be selected)
-- rgbw: [3] RGB-weights []. Weigh the color channels. ex: [0.26, 0.55, 0.19]
-- bits: 1-8 Bits used for each color channel in palette
-- quantpow: 0..1 Quantity vs Quality (put weight into histogram/pixelcount)
-- briweight: 0..1 Brightness distance weight in colordistance
-- proxweight: 0..1 Primary Proximity distance weight in colordistance (ColorTheory-WIP: compensate for brightness of individual channels, the "extra power" of primary colors)
--
-- return: A palette! A list of [r,g,b] values
--
-- NOTE: Quantity will act as a counterforce to altered colorspace (weights)...
-- Ex: if Green is considered bigger, it will be split into more blocks
-- but each blocks will have less colors and thus less quantity.
--
-- Perceptual colorspace (rgb-weights) will generally produce the best quality of palettes, but if
-- It's desirable to preserve stronger colors, esp. in small palettes,
-- it can be good to just use nominal space: 0.33, 0.33, 0.33
--
-- Histogram may be useful to assign more colors to an object that already covers most of the image,
-- however; if the object of interest is small in relation to a large (unimportant) background, it's
-- usually best not to have any histogram at all. Histogram will dampen strong infrequent colors.
 
 
function db.medianRedux(pal,cnum,qual,quant,rgbw,bits,quantpow, briweight, proxweight) -- pal[r,g,b,i,pixelcount]
local n,x,y,xs,ys,rgb,blocklist,blocks
local len,res,chan,diff,maxdiff,maxblock,split
local qualnorm, quantnorm,count
 
blocklist = {}
blocklist[1] = {}; blocks = 1
 
count = 0
for n=1, #pal, 1 do
blocklist[1][n] = pal[n];
count = count + pal[n][5]
end
 
-- Normalize 256 for quality/quantity relationship
qualnorm = 1 / math.sqrt(rgbw[1]^2 + rgbw[2]^2 + rgbw[3]^2)
quantnorm = 256 / count
 
 
-- Dist table
statusmessage("MR: Making Distance Table..."); updatescreen(); if (waitbreak(0)==1) then return; end
local dy,c,r1,g1,b1,i1,i2
dt = {}
for n=1, #pal, 1 do
c = pal[n]
r1,g1,b1,i1 = c[1],c[2],c[3],c[4]
dt[i1+1] = {}
for m=1, #pal, 1 do
dt[i1+1][pal[m][4]+1] = db.getColorDistanceProx(r1,g1,b1,pal[m][1],pal[m][2],pal[m][3],rgbw[1],rgbw[2],rgbw[3],qualnorm, proxweight, briweight) -- pri/bri
end
end
--
 
statusmessage("MR: Analyzing Block 1..."); updatescreen(); if (waitbreak(0)==1) then return; end
r_analyzeBlock(dt,blocklist[1],qual,quant,rgbw,qualnorm,quantnorm,quantpow)
 
statusmessage("MR: Analyzing Blocks..."); updatescreen(); if (waitbreak(0)==1) then return; end
failsafe = 0
while (blocks < cnum and failsafe < 256) do
failsafe = failsafe + 1
maxdiff = -1
maxblock = -1
for n=1, blocks, 1 do
diff = blocklist[n].diff
if (diff > maxdiff) then maxdiff = diff; maxblock = n; end -- maxchan is stored as .chan in block
end
split = r_splitBlock(dt,blocklist,maxblock,qual,quant,rgbw,qualnorm,quantnorm,quantpow)
if (split == false) then messagebox("Only found "..blocks.." (24-bit) colors!"); break; end
blocks = #blocklist
statusmessage("MR: "..blocks); updatescreen(); if (waitbreak(0)==1) then return; end
end -- while
 
return r_blocks2Palette(blocklist,bits)
 
end
--
 
--
function r_blocks2Palette(blocklist,bits)
local n,r,g,b,c,pal,block,rgb,blen,M,dB,cB,rf,gf,bf
M = math
pal = {}
 
--bits = 1
dB = M.pow(2,8-bits)
cB = M.ceil(255 / (M.pow(2,bits) - 1))
 
for n=1, #blocklist, 1 do
block = blocklist[n]
r,g,b = 0,0,0
blen = #block
for c=1, blen, 1 do
rgb = block[c]
r = r + rgb[1]
g = g + rgb[2]
b = b + rgb[3]
end
 
rf = M.floor(M.min(255,M.max(0,M.floor(r/blen))) / dB) * cB
gf = M.floor(M.min(255,M.max(0,M.floor(g/blen))) / dB) * cB
bf = M.floor(M.min(255,M.max(0,M.floor(b/blen))) / dB) * cB
 
pal[n] = {rf, gf, bf} -- col is avg. of all colors in block
end -- blocklist
 
return pal
end
--
 
--
function r_analyzeBlock(dt,block,qual,quant,rgbw,qualnorm,quantnorm,quantpow)
local r,g,b,n,m,rmin,gmin,bmin,rmax,gmax,bmax,rdif,gdif,bdif,chan,d,median,diff
local len,Mm,Mx,rgb,kv,qu
local maxdist,dist,r1,g1,b1,r2,g2,b2,c1,c2,count
 
Mx,Mm = math.max, math.min
len = #block
 
rmin,gmin,bmin = 255,255,255
rmax,gmax,bmax = 0,0,0
maxdist,c1,c2,count = 0,-1,-1,0
 
for n=1, len, 1 do
rgb1 = block[n]
count = count + rgb1[5] -- pixelcount for color
for m=n+1, len, 1 do
rgb2 = block[m]
--dist = db.getColorDistanceProx(r1,g1,b1,r2,g2,b2,0.26,0.55,0.19,1.569, 0.1, 0.25) -- pri/bri
dist = dt[rgb1[4]+1][rgb2[4]+1]
 
if dist > maxdist then
maxdist = dist
c1 = rgb1[4]+1
c2 = rgb2[4]+1
end
end
end
-- quantity and quality are normalized to 256 (256 is the total of colors in the set for quantity)
-- Note that, regardless of forumla, quality (distance) must always be greater in any block than quantity (colors/pixels)
-- Coz a block may contain many of only 1 unique color, thus rendering it impossible to split if selected.
kv = 1
qu = 1
if (quant) then kv = math.pow(1 + count*quantnorm*quantpow, 0.5); end
if (qual) then qu = maxdist * qualnorm; end
diff = qu*(1-quantpow) + qu*kv
 
block.chan = -1
block.diff = diff
block.median = -1
block.c1 = c1
block.c2 = c2
 
return {diff,len}
 
end
--
 
function r_splitBlock(dt,blocklist,maxblock,qual,quant,rgbw,qualnorm,quantnorm,quantpow)
local n,cmax,median,blockA,blockB,len,cB,block,rgb,res
local c1,c2,dist1,dist2,medr,medg,medb,r1,g1,b1,r2,g2,b2,rgb1,rgb2
 
blockA,blockB = {},{}
block = blocklist[maxblock]
 
res = true
 
--chan = block.chan
--median = block.median
c1 = block.c1
c2 = block.c2
 
--rgb1 = block[c1]
--r1,g1,b1 = rgb1[1],rgb1[2],rgb1[3]
--rgb2 = block[c2]
--r2,g2,b2 = rgb2[1],rgb2[2],rgb2[3]
--medr = (r1+r2)/2
--medg = (g1+g2)/2
--medb = (b1+b2)/2
 
cB = blocklist[maxblock] -- maxblock starts at 1 when called so it should not hava a +1
len = #cB
 
if len < 2 then return false; end
 
for n=1, len, 1 do
rgb = cB[n]
dist1 = dt[rgb[4]+1][c1]
dist2 = dt[rgb[4]+1][c2]
 
if (dist1 <= dist2)
then table.insert(blockA,rgb);
end
 
if (dist1 > dist2) then
table.insert(blockB,rgb);
end
end
 
blocklist[maxblock] = blockA -- Can't be empty right?
r_analyzeBlock(dt,blocklist[maxblock],qual,quant,rgbw,qualnorm,quantnorm,quantpow)
 
if (#blockB > 0) then
table.insert(blocklist,blockB)
r_analyzeBlock(dt,blocklist[#blocklist],qual,quant,rgbw,qualnorm,quantnorm,quantpow) -- no -1 on blocklist
else
res = false
end
 
return res -- false = no split
end
 
------------ eof MEDIAN REDUX --------------------------
 
 
 
 
--
-- ... eof Custom Color / Palette functions ...
--
 
 
-- *****************************
-- *** Custom Draw functions ***
-- *****************************
 
--
function db.line(x1,y1,x2,y2,c) -- Coords should be integers or broken lines are possible
local n,st,m,xd,yd; m = math
st = m.max(1,m.abs(x2-x1),m.abs(y2-y1));
xd = (x2-x1) / st
yd = (y2-y1) / st
for n = 0, st, 1 do
putpicturepixel(m.floor(x1 + n*xd), m.floor(y1 + n*yd), c );
end
end
--
 
--
function db.lineTransp(x1,y1,x2,y2,c,amt) -- amt: 0-1, 1 = Full color
local n,st,m,x,y,r,g,b,r1,g1,b1,c2,org; m = math
org = 1 - amt
st = m.max(1,m.abs(x2-x1),m.abs(y2-y1));
for n = 0, st, 1 do
x = m.floor(x1+n*(x2-x1)/st)
y = m.floor(y1+n*(y2-y1)/st)
r,g,b = getcolor(getpicturepixel(x,y))
r1,g1,b1 = getcolor(c)
c2 = matchcolor(r1*amt+r*org, g1*amt+g*org, b1*amt+b*org)
putpicturepixel(x, y, c2 );
end
end
--
 
--
function db.drawBrushRectangle(x1,y1,w,h,c)
local x,y
for y = y1, y1+h-1, 1 do
for x = x1, x1+w-1, 1 do
putbrushpixel(x,y,c);
end
end
end
--
 
--
function db.drawRectangle(x1,y1,w,h,c)
local x,y
for y = y1, y1+h-1, 1 do
for x = x1, x1+w-1, 1 do
putpicturepixel(x,y,c);
end
end
end
--
 
--
function db.drawRectangleNeg(x1,y1,w,h,c)
local x,y,xs,ys
xs = db.sign(w)
ys = db.sign(h)
if xs == 0 then xs = 1; end
if ys == 0 then ys = 1; end
for y = y1, y1+h-1, ys do
for x = x1, x1+w-1, xs do
putpicturepixel(x,y,c);
end
end
end
--
 
--
function db.drawRectangleLine(x,y,w,h,c)
w = w-1
h = h-1
db.line(x,y,x+w,y,c)
db.line(x,y,x,y+h,c)
db.line(x,y+h,x+w,y+h,c)
db.line(x+w,y,x+w,y+h,c)
end
--
 
 
--
function db.drawRectangleMix(x1,y1,w,h,c1,c2)
local x,y,c,n
c = {c1,c2}
n = 0
for y = y1, y1+h-1, 1 do
n = n + 1
for x = x1, x1+w-1, 1 do
n = n + 1
putpicturepixel(x,y,c[n%2+1]);
end
end
end
--
 
--
function db.drawCircle(x1,y1,r,c) -- ok, lottsa weird adjustments here, can probably be optimized...
local x,y,d,r5,r25,r2,xr5,yr5
r5,r25,r2,xr5,yr5 = r+0.5,r-0.25,r*2, x1-r-0.5, y1-r-0.5
for y = 0, r2, 1 do
for x = 0, r2, 1 do
d = math.sqrt((x-r5)^2 + (y-r5)^2)
if d < r25 then putpicturepixel(x + xr5, y + yr5,c); end
end
end
end
--
 
--
function db.drawBrushCircle(x1,y1,r,c) -- ok, lottsa weird adjustments here, can probably be optimized...
local x,y,d
for y = 0, r*2, 1 do
for x = 0, r*2, 1 do
d = math.sqrt((x-r-0.5)^2 + (y-r-0.5)^2)
if d < r-0.25 then putbrushpixel(x1+x-r-0.5,y1+y-r-0.5,c); end
end
end
end
--
 
--
-- Rotation in degrees
-- Step is # of line segments (more is "better")
-- a & b are axis-radius
function db.ellipse2(x,y,a,b,stp,rot,col)
local n,m=math,rad,al,sa,ca,sb,cb,ox,oy,x1,y1,ast
m = math; rad = m.pi/180; ast = rad * 360/stp;
sb = m.sin(-rot * rad); cb = m.cos(-rot * rad)
for n = 0, stp, 1 do
ox = x1; oy = y1;
sa = m.sin(ast*n) * b; ca = m.cos(ast*n) * a
x1 = x + ca * cb - sa * sb
y1 = y + ca * sb + sa * cb
--if (n > 0) then db.line(ox,oy,x1,y1,col); end
if (n > 0) then drawline(ox,oy,x1,y1,col); end
end
end
--
 
 
 
--[[
var ER = 0.3
var DR = 0.15
 
ellipse(0.5*xx,0.5*yy,DR*xx,6,Math.PI*0)
 
function ellipse(x,y,r,stp,rot){
var n,deg=360,m=Math,rad=Math.PI/180,rn
var ox,oy,x1,y1,x2,y2,d1,r1 = ER * xx
for (n=0; n<=deg; n+=stp){
 
ox = x2; oy = y2, rn = rad * n
d1 = rn - rot
x1 = x + m.sin(d1) * r
y1 = y + m.cos(d1) * r
 
x2 = x1 + m.sin(-rn) * r1
y2 = y1 + m.cos(-rn) * r1
if (n > 0){ line_rgb(MX,[0,0,0],0,ox,oy,x2,y2) }
}
}
 
}
 
ellipse2(0.5*xx,0.5*yy,15,8,200,22,[0,0,0],0.5)
 
function ellipse2(x,y,a,b,stp,rot,rgb,transp){
var n,m=Math,rad=m.PI/180,al,sa,ca,sb,cb,ox,oy,x1,y1
sb = m.sin(-rot * rad); cb = m.cos(-rot * rad)
for (n=0; n<=stp; n++){
ox = x1; oy = y1; al = rad * 360/stp * n
sa = m.sin(al) * b; ca = m.cos(al) * a
x1 = x + ca * cb - sa * sb
y1 = y + ca * sb + sa * cb
if (n > 0){ line_rgb(MX,rgb,transp,ox,oy,x1,y1) }
}
}
 
 
]]
 
 
 
function db.obliqueCube(side,x,y,r,g,b,bri,cols)
local n,c,depth,x1,y1,x2,y2,f
 
asscols = false
if cols >= 0 and cols<250 then
asscols = true
c = cols; setcolor(cols,r,g,b); cols = cols + 1
cP50 = cols; q = bri*0.5; setcolor(cols,r+q,g+q,b+q); cols = cols + 1;
cP75 = cols; q = bri*0.75; setcolor(cols,r+q,g+q,b+q); cols = cols + 1;
cM50 = cols; q = -bri*0.5; setcolor(cols,r+q,g+q,b+q); cols = cols + 1;
cM100= cols; q = -bri; setcolor(cols,r+q,g+q,b+q); cols = cols + 1;
end
 
f = matchcolor
if asscols == false then
c = f(r,g,b)
cP50 = f(r+bri*0.5,g+bri*0.5,b+bri*0.5)
cP75 = f(r+bri*0.75,g+bri*0.75,b+bri*0.75)
cM50 = f(r-bri*0.5,g-bri*0.5,b-bri*0.5)
cM100 = f(r-bri,g-bri,b-bri)
end
 
 
depth = math.floor(side / 2)
 
for n = 0, depth-1, 1 do
db.line(x+side+n,y-1-n,x+side+n,y+side-n-1,cM50)
--drawline(x+side+n,y-1-n,x+side+n,y+side-n-1,cM50)
end
 
for n = 0, depth-1, 1 do
db.line(x+n,y-1-n,x+side+n-1,y-1-n,cP50)
--drawline(x+n,y-1-n,x+side+n-1,y-1-n,cP50)
end
 
-- /
--
--db.line(x+side,y-1,x+side+depth-1,y-depth,c)
 
-- Smoothing & Shade
 
--
-- /
--db.line(x+side,y+side-1,x+side+depth-1,y+side-depth,cM100)
 
--db.line(x,y,x+side-2,y,cP75)
--db.line(x,y,x,y+side-2,cP75)
 
db.drawRectangle(x,y,side,side,c)
 
return cols
 
end
 
 
function db.obliqueCubeBRI(side,x,y,r,g,b,bri,pallist,briweight,index_flag)
local n,c,depth,x1,y1,x2,y2
 
--f = db.getBestPalMatchHYBRID
c = db.getBestPalMatchHYBRID({r,g,b}, pallist, briweight, index_flag)
cP50 = db.getBestPalMatchHYBRID({r+bri*0.5,g+bri*0.5,b+bri*0.5}, pallist, briweight, index_flag)
cP75 = db.getBestPalMatchHYBRID({r+bri*0.75,g+bri*0.75,b+bri*0.75}, pallist, briweight, index_flag)
cM50 = db.getBestPalMatchHYBRID({r-bri*0.5,g-bri*0.5,b-bri*0.5}, pallist, briweight, index_flag)
cM100 = db.getBestPalMatchHYBRID({r-bri,g-bri,b-bri}, pallist, briweight, index_flag)
 
depth = math.floor(side / 2)
 
db.drawRectangle(x,y,side,side,c)
 
for n = 0, depth-1, 1 do
db.line(x+side+n,y-1-n,x+side+n,y+side-n-1,cM50)
--drawline(x+side+n,y-1-n,x+side+n,y+side-n-1,cM50)
end
 
for n = 0, depth-1, 1 do
db.line(x+n,y-1-n,x+side+n-1,y-1-n,cP50)
--drawline(x+n,y-1-n,x+side+n-1,y-1-n,cP50)
end
 
-- /
--
db.line(x+side,y-1,x+side+depth-1,y-depth,c)
--drawline(x+side,y-1,x+side+depth-1,y-depth,c)
 
 
-- Smoothing & Shade
 
--
-- /
--db.line(x+side,y+side-1,x+side+depth-1,y+side-depth,cM100)
 
--db.line(x,y,x+side-2,y,cP75)
--db.line(x,y,x,y+side-2,cP75)
 
 
end
 
 
--
function db.fillTriangle(p,fcol,lcol,fill,wire) -- p = list of 3 points
 
local n,x,y,x1,x2,y1,y2,xf,yf,len,mr
mr = math.floor
 
-- Convert to screen/matrix-coordinates
--if (mode == 'percent') then xf = xx / 100; yf = yy / 100; end
--if (mode == 'fraction') then xf = xx; yf = yy; end
--if (mode ~= 'absolute') then screenilizeTriangle(p,xf,yf); end
 
if (fill) then
local Ax,Ay,Bx,By,Cx,Cy,xd,a,b,yc,ABdy,BCdy,ABix,BCix,ACix
 
xd = {}
 
--sort(p,1) -- Find top and middle y-point
db.sorti(p,2)
 
Ay = p[1][2]; Ax = p[1][1]
By = p[2][2]; Bx = p[2][1]
Cy = p[3][2]; Cx = p[3][1]
 
ABdy = By - Ay
BCdy = Cy - By
ABix = (Bx - Ax) / ABdy
BCix = (Cx - Bx) / BCdy
ACix = (Cx - Ax) / (Cy - Ay)
 
a=1; b=2;
if (ACix < ABix) then a=2; b=1; end
for y = 0, ABdy-1, 1 do -- Upper -1
xd[a] = mr(Ax + ABix * y)
xd[b] = mr(Ax + ACix * y)
yc = y+Ay;
for x=xd[1], xd[2], 1 do
putpicturepixel(x,yc,fcol)
end
end
 
a=1; b=2;
if (BCix < ACix) then a=2; b=1; end
for y = 0, BCdy, 1 do -- Lower
xd[a] = mr(Cx - BCix * y);
xd[b] = mr(Cx - ACix * y)
yc = Cy-y;
for x = xd[1], xd[2], 1 do
putpicturepixel(x,yc,fcol)
end
end
 
end -- eof fill
if (wire) then
for n = 0, 2, 1 do -- Outline
x1 = p[n+1][1]; y1 = p[n+1][2]
x2 = p[1 + (n+1) % 3][1]; y2 = p[1 + (n+1) % 3][2]
--db.line(x1,y1,x2,y2,lcol)
drawline(x1,y1,x2,y2,lcol)
end
end
 
end -- eof fillTriangle
--
 
--
-- ... eof Custom Draw functions ...
--
 
 
-- ******************************
-- *** Filters & Convolutions ***
-- ******************************
 
 
function db.applyConvolution2Pic(convmx,divisor,bias,neg,amt)
local r,g,b,mx,my,cx,cy,mxh,myh,mp,rb,gb,bb,xx,yy,x,y,w,h,div,n1,n2,amtr,ro,go,bo
 
n1 = 1
n2 = bias
if neg == 1 then
n1 = -1
n2 = 255 + bias
end
amtr = 1 - amt
w, h = getpicturesize()
cy = #convmx
cx = #convmx[1]
mxh = math.floor(cx / 2) + 1
myh = math.floor(cy / 2) + 1
 
for y = 0, h-1, 1 do
for x = 0, w-1, 1 do
r,g,b = 0,0,0
ro,go,bo = getcolor(getbackuppixel(x,y))
div = divisor
for my = 1, cy, 1 do
for mx = 1, cx, 1 do
xp = mx-mxh
yp = my-myh
mp = convmx[my][mx]
xx = x + xp
yy = y + yp
if yy>=0 and yy<h and xx>=0 and xx<w then
rb,gb,bb = getcolor(getbackuppixel(xx,yy))
r = r + rb * mp
g = g + gb * mp
b = b + bb * mp
else div = div - mp -- Assumes divisor is the sum of the convolution matrix
end
end
end
r = ro*amtr + (n2 + (n1 * r) / div)*amt -- +bias
g = go*amtr + (n2 + (n1 * g) / div)*amt
b = bo*amtr + (n2 + (n1 * b) / div)*amt
putpicturepixel(x,y,matchcolor(r,g,b))
end;
updatescreen(); if (waitbreak(0)==1) then return; end
end;
 
end
 
--
-- ... eof Filters & Convolutions ...
--
 
 
 
-- *****************************
-- *** Fractals etc. ***
-- *****************************
 
-- Fractal Pattern V1.0 by Richard Fhager (mod allows for wrapping)
--
-- Pattern matrix example: {{1,1,1},{1,0,1},{1,1,1}}
--
function db.pattern(x,y,p,n,i) -- coord as fraction of 1, pattern, offset(0), iterations (1-15)
local px,py
py = #p
px = #p[1]
while ((p[1+math.abs(math.floor(y*py))%py][1+math.abs(math.floor(x*px))%px]) > 0 and n<i) do
x=x*px-math.floor(x*px);
y=y*py-math.floor(y*py);
n = n+1
end
return 1 - n/i;
end
--
 
--
function db.patternDec(x,y,p,n,i) -- coord as fraction of 1, pattern, offset(0), iterations (1-15)
local px,py,spfrac,nfrac,fx,fy
spfrac = 1
nfrac = 0
py = #p
px = #p[1]
while (spfrac > 0 and n<i) do
fy = math.floor(math.abs(y*py))%py
fx = math.floor(math.abs(x*px))%px
spfrac = p[fy+1][fx+1]
if (spfrac>0) then
x = x*px - fx
y = y*py - fy
nfrac = nfrac + spfrac
end
n = n+1
end
--return 1 - n/i;
return 1 - nfrac/i
end
--
 
 
--
function db.mandel(x,y,l,r,o,i) -- pos. as fraction of 1, left coord, right coord, y coord, iterations
 
local w,s,a,p,q,n,v,w
 
s=math.abs(r-l);
 
a = l + s*x;
p = a;
b = o - s*(y-0.5);
q = b;
n = 1;
v = 0;
w = 0;
 
while (v+w<4 and n<i) do n=n+1; v=p*p; w=q*q; q=2*p*q+b; p=v-w+a; end;
 
return n
end
--
 
--
-- ... eof Fractals etc. ...
--
 
 
-- ********************************************
-- *** Color Cube / Space, Custom Functions ***
-- ********************************************
--
-- SHADES (sha): 24bit colors is too complex so we operate with less shades/bits/colors.
-- 16 shades = 12bit = 16*16*16 = 4096 colors (or cubic-elements)
-- 32 shades = 15bit = 32*32*32 = 32768 colors
 
--
-- data: {color available flag, 0 (gravity/distance, calculated, init as zero)}
--
function db.initColorCube(sha,data)
local ary,z,y,x,n
ary = {}
for z = 0, sha-1, 1 do
ary[z+1] = {}
for y = 0, sha-1, 1 do
ary[z+1][y+1] = {}
if data ~= nil then
for x = 0, sha-1, 1 do
-- This is silly stupid, if you know how to assign one array to another (no ref), plz help!
-- i.e. how to: data = {false,0}; myArray[z][y][x] = data.
ary[z+1][y+1][x+1] = {}
for n = 1, #data, 1 do
ary[z+1][y+1][x+1][n] = data[n]
end
end
end
end
end
return ary
end
--
 
--
function db.findVoid(cube,sha) -- void is point with longest distance to closest color
local weakest,weak_i,x,y,z,c,w
weakest = -1
weak_i = {-1,-1,-1}
for z = 0, sha-1, 1 do
for y = 0, sha-1, 1 do
for x = 0, sha-1, 1 do
c = cube[z+1][y+1][x+1]
if c[1] == true then
w = c[2]
if w > weakest then weakest = w; weak_i = {z,y,x}; end
end
end;end;end
return weak_i[1],weak_i[2],weak_i[3]
end
--
 
--
--
-- Nearest color version: void is selected by the point that has the greatest distance
-- to the nearest color. Higher value means greater void.
--
function db.addColor2Cube(cube,sha,r,g,b,rw,gw,bw)
local star,x,y,z,d,rd,gd,bd,cu1,cu2
star = 0
cube[r+1][g+1][b+1] = {false, star}
for z = 0, sha-1, 1 do
rd = (rw*(z-r))^2
cu2 = cube[z+1]
for y = 0, sha-1, 1 do
gd = (gw*(y-g))^2
cu1 = cu2[y+1]
for x = 0, sha-1, 1 do
d = rd + gd + (bw*(x-b))^2
 
--cube[z+1][y+1][x+1][2] = math.min(d, cube[z+1][y+1][x+1][2]) -- Don't add, use nearest color
 
cu1[x+1][2] = math.min(d, cu1[x+1][2])
 
end;end;end
end
--
 
-- Should be same as original, but not 100% verified. Using a rgb+1 trick to speed up handling
--
function db.addColor2Cube_test(cube,sha,r,g,b,rw,gw,bw)
local star,x,y,z,d,rd,gd,bd,cu1,cu2
star = 0
r = r+1; g = g+1; b = b+1
cube[r][g][b] = {false, star}
for z = 1, sha, 1 do
rd = (rw*(z-r))^2
cu2 = cube[z]
for y = 1, sha, 1 do
gd = (gw*(y-g))^2
cu1 = cu2[y]
for x = 1, sha, 1 do
cu1[x][2] = math.min(rd+gd+(bw*(x-b))^2, cu1[x][2])
end;end;end
end
--
 
 
 
-- Create new allowed colorlines in colorspace (ramps from which colors can be picked)
function db.enableRangeColorsInCube(cube,sha,r1,g1,b1,r2,g2,b2)
 
local div,r,g,b,n,rs,gs,bs
div = 256 / sha
rs = (r2 - r1) / sha / div
gs = (g2 - g1) / sha / div
bs = (b2 - b1) / sha / div
 
for n = 0, sha-1, 1 do
 
r = math.floor(r1/div + rs * n)
g = math.floor(g1/div + gs * n)
b = math.floor(b1/div + bs * n)
 
cube[r+1][g+1][b+1][1] = true
 
end
end
--
 
 
function db.colorCigarr(shades,radius,fill_flag)
local s,rad,radsq,step,shalf,bas,cols,found,x,y,z,bri,con,d,n
radius = radius / 100
step = math.floor(255 / (shades-1))
shalf = math.floor(shades / 2)
s = shades - 1
rad = math.floor(shades / 2 * radius)
radsq = rad^2
 
bas = 0
cols = {}
found = 0
 
for z = 0, s, 1 do
for y = 0, s, 1 do
for x = 0, s, 1 do
 
--0.26,0.55,0.19
bri = (x + y + z ) / 3
--bri = math.sqrt(((x*0.26)^2 + (y*0.55)^2 + (z*0.19)^2)) * 1.5609
con = math.floor((shades - math.abs(bri - shalf)*2) * radius)
 
d = math.floor(math.sqrt((bri-x)^2 + (bri-y)^2 + (bri-z)^2))
--d = math.floor(math.sqrt(((bri-x)*0.26)^2 + ((bri-y)*0.55)^2 + ((bri-z)*0.19)^2)) * 1.5609
 
-- Filled cigarr: Less or Equal, cigarr shell: Equal
if d == con or (d < con and fill_flag) then
found = found + 1
r = bas + x * step
g = bas + y * step
b = bas + z * step
cols[found] = {r,g,b}
end
 
end; end; end
 
--messagebox("Colors found: "..found.."\n\n".."Run AnalyzePalette to examine")
 
for n = 0, 255, 1 do
if n < found then
c = cols[n+1]
setcolor(n,c[1],c[2],c[3])
else
setcolor(n,0,0,0)
end
end
end -- eof colorcigarr
 
 
--
-- ... eof Color Cube ...
--
 
 
 
-- COLORMIX --
--
-- Returns a list of mixcolors palette entries, that are ranked by by quality & usefulness
--
-- This whole junk my partly locked on 16 shades (4096 colors/ 12bit palette precision) so don't use anything else...
--
--
function db.colormixAnalysis(sha,spare_flag,cust_dist) -- Interface
local shades,pallist,ilist,custom_max_distance
 
shades = sha -- 16 is good
--messagebox(shades)
 
custom_max_distance = -1
if cust_dist ~= null then
custom_max_distance = cust_dist -- in %
end
 
if spare_flag == true then -- No shades here for now
--pallist = db.makePalListShadeSPARE(256,shades) -- 16 shades so Colorcube processes is possible
pallist = db.makeSparePalList(256)
pallist = db.fixPalette(pallist,0) -- Remove doubles, No need to sort?
ilist = db.makeIndexList(pallist, -1) -- -1, use list order as index
else
pallist = db.makePalListShade(256,shades) -- 16 shades so Colorcube processes is possible
pallist = db.fixPalette(pallist,0) -- Remove doubles, No need to sort?
ilist = db.makeIndexList(pallist, -1) -- -1, use list order as index
end
 
if shades > 0 then
return db.colormixAnalysisEXT(shades,pallist,ilist,custom_max_distance) -- max distance in %
end
if shades == -1 then
return db.colormixAnalysisEXTnoshade(pallist,ilist,custom_max_distance) -- max distance in %
end
end
--
--
function db.colormixAnalysisEXT(SHADES,pallist,ilist,custom_max_distance) -- Shades, most number of mixes returned
local n,m,c1,c2,pairs,cube,rm,gm,bm
local mix,total,found,dist,void,ideal,mini,maxi,bestmix,bestscore
--messagebox("will now make pairs")
 
pairs = db.pairsFromList(ilist,0) -- 0 for unique pairs only, pairs are entries in pallist
 
--messagebox(#pairs.." will now add colors to cube")
 
cube = db.initColorCube(SHADES,{true,9999})
for n = 1, #pallist, 1 do
c1 = pallist[n]
db.addColor2Cube_test(cube,SHADES,c1[1],c1[2],c1[3],0.26,0.55,0.19)
end
 
-- these values are adjusted for a 12bit palette (0-15) and perceptual weight where r+g+b = 1.0
-- Ideal distance = 2.5 Green steps = 1.375
-- Minimum distance = 1 Green step = 0.55
 
--messagebox("colorcube done")
 
VACT = 1
DACT = 1
 
total = 9.56 -- Max distance possible with 16 shades
ideal = 0.45 -- 1 step = 0.637
mini = 0.35
maxi = ideal + (total - ideal) / math.max(1, #pallist / 16)
if custom_max_distance ~= -1 then
maxi = total * (custom_max_distance / 100)
end
mix = {}
--mix[1] = {9e99,0,0,9e99,0,0,0}
bestmix = -1
bestscore = 9e99
found = 0
for n = 1, #pairs, 1 do
 
c1 = pallist[pairs[n][1]]
c2 = pallist[pairs[n][2]]
--0.26,0.55,0.19
dist = db.getColorDistance_weight(c1[1],c1[2],c1[3],c2[1],c2[2],c2[3],0.26,0.55,0.19) -- Not normalized
 
rm = math.floor((c1[1]+c2[1])/2)
gm = math.floor((c1[2]+c2[2])/2)
bm = math.floor((c1[3]+c2[3])/2)
 
-- Mix color adjustment (perhaps less than perfect, but probably good enough)
mixbri = db.getBrightness(rm,gm,bm)
truebri = math.sqrt((db.getBrightness(c1[1],c1[2],c1[3])^2 + db.getBrightness(c2[1],c2[2],c2[3])^2) / 2)
diff = truebri - mixbri
rm = math.max(0,math.min(15,math.floor(rm + diff)))
gm = math.max(0,math.min(15,math.floor(gm + diff)))
bm = math.max(0,math.min(15,math.floor(bm + diff)))
newbri = db.getBrightness(rm,gm,bm)
delta = math.abs(newbri - truebri)
--if delta > 0.9 then
-- messagebox(pallist[pairs[n][1]][4]..", "..pallist[pairs[n][2]][4].." delta = "..delta)
--end
--
 
--rm = math.floor(math.sqrt((c1[1]^2 + c2[1]^2) / 2))
--gm = math.floor(math.sqrt((c1[2]^2 + c2[2]^2) / 2))
--bm = math.floor(math.sqrt((c1[3]^2 + c2[3]^2) / 2))
 
void = cube[rm+1][gm+1][bm+1][2]
 
if dist >= mini and dist <= maxi then
found = found + 1
score = ((1+DACT*(dist - ideal)^2) / (1+void*VACT)) -- Lowest is best
mix[found] = {score,pallist[pairs[n][1]][4],pallist[pairs[n][2]][4],dist,rm*SHADES,gm*SHADES,bm*SHADES,c1[1]*SHADES,c1[2]*SHADES,c1[3]*SHADES,c2[1]*SHADES,c2[2]*SHADES,c2[3]*SHADES} -- mix holds palette entry
if score < bestscore then bestscore = score; bestmix = found; end
end
 
end
 
 
if true == false then
-- 2nd pass, add bestmix to colorspace. This reduces many similar mixes.
m = mix[bestmix]
db.addColor2Cube(cube,SHADES,m[5],m[6],m[7],0.26,0.55,0.19)
for n = 1, #mix, 1 do
if n ~= bestmix then
m = mix[n]
dist = m[4]
void = cube[m[5]+1][m[6]+1][m[7]+1][2]
score = ((1+DACT*(dist - ideal)^2) / (1+void*VACT))
m[1] = score
end
end
end
 
c1,c2 = -1,-1
if found > 0 then
db.sorti(mix,1)
best = mix[1]
c1 = best[2]
c2 = best[3]
end
 
--return found,c1,c2
return mix,found,c1,c2
end
--
 
 
--
-- Mixcolor without colorcube - no scoring or sorting, 24bit colors, faster...
--
function db.colormixAnalysisEXTnoshade(pallist,ilist,custom_max_distance)
local n,m,c1,c2,pairs,cube,rm,gm,bm
local mix,total,found,dist,void,ideal,mini,maxi,bestmix,bestscore
 
pairs = db.pairsFromList(ilist,0) -- 0 for unique pairs only, pairs are entries in pallist
 
total = 162.53 -- Max distance possible with 24-bit palette ad Dawn3.0 color weights 162.53
ideal = 0
mini = 0
maxi = ideal + (total - ideal) / math.max(1, #pallist / 16)
 
if custom_max_distance ~= -1 then
maxi = total * (custom_max_distance / 100)
end
 
statusmessage("Mixcol Analysis ("..#pairs.." pairs) ");
updatescreen(); if (waitbreak(0)==1) then return; end
 
mix = {}
found = 0
for n = 1, #pairs, 1 do
c1 = pallist[pairs[n][1]]
c2 = pallist[pairs[n][2]]
--0.26,0.55,0.19
dist = db.getColorDistance_weight(c1[1],c1[2],c1[3],c2[1],c2[2],c2[3],0.26,0.55,0.19) -- Not normalized
 
rm = math.floor((c1[1]+c2[1])/2)
gm = math.floor((c1[2]+c2[2])/2)
bm = math.floor((c1[3]+c2[3])/2)
 
-- Mix color adjustment
mixbri = db.getBrightness(rm,gm,bm)
truebri = math.sqrt((db.getBrightness(c1[1],c1[2],c1[3])^2 + db.getBrightness(c2[1],c2[2],c2[3])^2) / 2)
diff = truebri - mixbri
rm = math.max(0,math.min(255,math.floor(rm + diff)))
gm = math.max(0,math.min(255,math.floor(gm + diff)))
bm = math.max(0,math.min(255,math.floor(bm + diff)))
newbri = db.getBrightness(rm,gm,bm)
delta = math.abs(newbri - truebri)
--if delta > 0.9 then
-- messagebox(pallist[pairs[n][1]][4]..", "..pallist[pairs[n][2]][4].." delta = "..delta)
--end
--
 
if dist >= mini and dist <= maxi then
found = found + 1
score = 1
mix[found] = {score,pallist[pairs[n][1]][4],pallist[pairs[n][2]][4],dist,rm,gm,bm,c1[1],c1[2],c1[3],c2[1],c2[2],c2[3]} -- mix holds palette entry
end
 
end
 
--messagebox(#mix)
 
return mix,found,-1,-1
end
--
 
 
 
-- Fuse a palettelist into an extended mix-anlysis list
function db.fusePALandMIX(pal,mix,max_score,max_dist)
local n,c,mixlist,tot,score,dist,c1,c2,rm,gm,bm
 
mixlist = {}
tot = 0
 
-- {r,g,b,n}
for n = 1, #pal, 1 do
tot = tot + 1
c = pal[n]
mixlist[tot] = {0,c[4],c[4],0,c[1],c[2],c[3],c[1],c[2],c[3],c[1],c[2],c[3]}
end
 
-- {score,col#1,col#2,dist,rm,gm,bm} low score is best
for n = 1, #mix, 1 do
score = mix[n][1]
dist = mix[n][4]
if score <= max_score and dist <= max_dist then
tot = tot + 1
mixlist[tot] = mix[n]
end
end
 
return mixlist
end
--
 
 
-- ********************************************
-- *** L-system (fractal curves & "plants") ***
-- ********************************************
--
 
--
function db.Lsys_makeData(a)
local n,i; i = {}
for n = 1, #a, 1 do i[a[n][2]] = a[n]; end
return i
end
--
 
--
function db.Lsys_makeSet(seed,iter,data)
local s,n,i,nset,set
set = seed
for n = 1, iter, 1 do
nset = ''
for i = 1, #set, 1 do
s = string.sub(set,i,i)
nset = nset..data[s][3]
end
set = nset
end
return set
end
--
 
function db.Lsys_draw(set,data,cx,cy,size,rot,rgb,rng,transp, speed)
local p,M,DEG,l,n,d,i,v,q,c,tx,ty,posx,posy,dval,col,w,h,s,cl,count
 
if speed == nil then speed = 50; end -- speed is drawing operations per update
 
function ang(d) return (d % 360 + 360) * DEG; end
w,h = getpicturesize()
 
p = 0
M = math
DEG = math.pi/180
l = #set
 
posx={}; posy={}; dval={}
 
if (rgb == null) then rgb = {0,0,0}; end
if (transp == null) then transp = 0; end
col = db.newArrayMerge(rgb,{})
q = 255 / l
 
count = 0
for n = 1, l, 1 do
s = string.sub(set,n,n)
d = data[s]
i = d[1]
v = d[4]
 
--messagebox(i)
 
if (i == 'Left') then rot = rot - v; end
if (i == 'Right') then rot = rot + v; end
if (i == 'Save') then p=p+1; posx[p] = cx; posy[p] = cy; dval[p] = rot; end
if (i == 'Load') then cx = posx[p]; cy = posy[p]; rot = dval[p]; p=p-1; end
 
if (i == 'Draw') then
tx = cx + M.sin(ang(rot)) * size
ty = cy + -M.cos(ang(rot)) * size
for c = 1, 3, 1 do
if (rng[c] > 0) then col[c] = rgb[c] + (n * q) * rng[c]; end
if (rng[c] < 0) then col[c] = rgb[c] + (n * q) * rng[c]; end
end
 
cl = matchcolor(col[1],col[2],col[3])
--putpicturepixel(cx*w,cy*h,cl);
--db.line(cx*w,cy*h,tx*w,ty*h,cl)
db.lineTransp(cx*w,cy*h,tx*w,ty*h,cl,transp)
cx = tx; cy = ty
end
count = count + 1
if count == speed then count = 0; updatescreen(); if (waitbreak(0)==1) then return end; end
end
 
return {cx,cy,rot}
end -- draw
 
 
--
-- eof L-system
--
---------------------------------------------------------------------------------------
 
 
 
-- ********************************************
-- *** COMPLEX SPECIAL FUNCTIONS ***
-- ********************************************
--
 
---------------------------------------------------------------------------------------
--
-- Render engine for mathscenes (Full Floyd-Steinberg dither etc)
--
function db.fsrender(f,pal,ditherprc,xdith,ydith,percep,xonly, ord_bri,ord_hue,bri_change,hue_change,BRIWEIGHT, wd,ht,ofx,ofy) -- f is function
 
local w,h,i,j,c,x,y,r,g,b,d,fl,v,v1,v2,vt,vt1,vt2,dither,m,mathfunc,dpow,fsdiv,ord,d1a,d1b,briweight
local d1,d2,o1,o2,ox,oy
 
-- percep is no longer used, matchcolor2 is always active, but the code is kept if there's ever a need to
-- study the effect of perceptual colorspaces versus matchcolor
 
if ord_bri == null then ord_bri = 0; end
if ord_hue == null then ord_hue = 0; end
if bri_change == null then bri_change = 0; end
if hue_change == null then hue_change = 0; end
if BRIWEIGHT == null then BRIWEIGHT = 0; end
 
briweight = BRIWEIGHT / 100
 
ord = {{0,4,1,5},
{6,2,7,3},
{1,5,0,4},
{7,3,6,2}}
 
--i = ((ord[y % 4 + 1][x % 4 + 1])*28.444 - 99.55556)/100 * 16
function hue(r,g,b,deg)
local i,brin,diff,brio,r2,g2,b2
r2,g2,b2 = db.shiftHUE(r,g,b,deg)
brio = db.getBrightness(r,g,b)
for i = 0, 5, 1 do -- 6 iterations, fairly strict brightness preservation
brin = db.getBrightness(r2,g2,b2)
diff = brin - brio
r2,g2,b2 = db.rgbcap(r2-diff, g2-diff, b2-diff, 255,0)
end
return r2,g2,b2
end
 
 
 
fsdiv = 16
if xonly == 1 then fsdiv = 7; end -- Only horizontal dither
 
dither = 0; if ditherprc > 0 then dither = 1; end
 
-- When using standard error-diffusion brightness-matching is not really compatible
--matchfunc = matchcolor2
--if dither == 1 then matchfunc = matchcolor; end
 
dpow = ditherprc / 100
 
 
if wd == null then
w,h = getpicturesize()
else w = wd; h = ht
end
 
if ofx == null then
ox,oy = 0,0
else ox = ofx; oy = ofy
end
 
 
function cap(v)
return math.min(255,math.max(0,v))
end
 
 
 
--
fl = {}
fl[1] = {}
fl[2] = {}
i = 1
j = 2
--
 
-- Read the first 2 lines
v1 = ydith/2 + 0%2 * -ydith
v2 = ydith/2 + 1%2 * -ydith
for x = 0, w - 1, 1 do
d1a,d1b = 0,0
if ord_bri > 0 then
o1 = ord[0 % 4 + 1][x % 4 + 1]
d1a = (o1*28.444 - 99.55556)/100 * ord_bri
o2 = ord[1 % 4 + 1][(x+2) % 4 + 1] -- +2 To get it in right sequence for some reason
d1b = (o2*28.444 - 99.55556)/100 * ord_bri
end
-- We skip Hue-ordering for now
vt1 = v1 + xdith/2 + (x+math.floor(0/2))%2 * -xdith + d1a
vt2 = v2 + xdith/2 + (x+math.floor(1))%2 * -xdith + d1b -- Ok, not sure why 1/2 doesn't make for a nice pattern so we just use 1
r,g,b = f(x, 0, w, h)
fl[i][x] = {cap(r+vt1),cap(g+vt1),cap(b+vt1)}
r,g,b = f(x, 1, w, h)
fl[j][x] = {cap(r+vt2),cap(g+vt2),cap(b+vt2)}
end
 
for y = 0, h-1, 1 do
for x = 0, w-1, 1 do
 
o = fl[i][x]
r = o[1] + bri_change
g = o[2] + bri_change
b = o[3] + bri_change
 
if hue_change ~= 0 then
r,g,b = hue(r,g,b,hue_change)
end
 
--if percep == 0 then c = matchfunc(r,g,b); end
--if percep == 1 then
-- --c = db.getBestPalMatchHYBRID({r,g,b},pal,0,true)
--c = matchcolor2(r,g,b,briweight)
--end
 
c = matchcolor2(r,g,b,briweight)
 
putpicturepixel(x+ox,y+oy,c)
 
if dither == 1 then
if x>1 and x<w-1 and y<h-1 then
rn,gn,bn = getcolor(c)
re = ((r - rn) / fsdiv) * dpow
ge = ((g - gn) / fsdiv) * dpow
be = ((b - bn) / fsdiv) * dpow
o = fl[i][x+1]; r,g,b = o[1],o[2],o[3]
fl[i][x+1] = {cap(r+re*7), cap(g+ge*7), cap(b+be*7)}
if xonly ~= 1 then
o = fl[j][x]; r,g,b = o[1],o[2],o[3]
fl[j][x] = {cap(r+re*5), cap(g+ge*5), cap(b+be*5)}
o = fl[j][x-1]; r,g,b = o[1],o[2],o[3]
fl[j][x-1] = {cap(r+re*3), cap(g+ge*3), cap(b+be*3)}
o = fl[j][x+1]; r,g,b = o[1],o[2],o[3]
fl[j][x+1] = {cap(r+re), cap(g+ge), cap(b+be)}
end
end
end
 
end
 
vt = 0
v = ydith/2 + y%2 * -ydith
-- Flip ED lines and read the nextline
i,j = j,i
for x = 0, w - 1, 1 do
 
d1,d2 = 0,0
if ord_bri > 0 then
o = ord[y % 4 + 1][x % 4 + 1]
d1 = (o*28.444 - 99.55556)/100 * ord_bri
end
vt = v + xdith/2 + (x+math.floor(y/2))%2 * -xdith + d1
r,g,b = f(x, y+2, w, h)
 
if ord_hue > 0 then
o = ord[y % 4 + 1][x % 4 + 1]
d2 = (((o + 3.5) % 7) / 7 - 0.5) * ord_hue
r,g,b = hue(r,g,b,d2)
end
fl[j][x] = {cap(r+vt),cap(g+vt),cap(b+vt)}
end
updatescreen(); if (waitbreak(0)==1) then return; end
end
 
 
end
-------------------------------------------------------------------------------
 
--
-- ROTATE Image or Brush
--
-- target: 1 = Brush, 2 = Picture, 3 = Brush-to-Picture
-- rot: Rotation in degrees
-- mode: 1 = Simple, 2 = Cosine Interpolation, 2 = BiLinear Interpolation
-- spritemode: 0 = Off, 1 = On (Only match adjacent colors, use with Bilinear-Ip. for good result)
-- resize: 0 = No, 1 = Yes (Resize Image/Brush to fit all gfx, otherwise clip)
-- update: 0 = No, 1 = Yes (Update screen while drawing)
-- xoffset: For use with Brush-to-Picture operations
-- yoffset: For use with Brush-to-Picture operations
--
function db.doRotation(target,rot,mode,spritemode,resize,update, xoffset,yoffset)
 
local trg,f,w,h,x,y,r,g,b,c,hub_x,hub_y,x1,y1,x2,y2,x3,y3,x4,y4,dX,dY,dXs,dYs,ox,oy,mx,my,xp,yp,pal,func
 
function donothing(n)
end
 
func = {
{getsize=getbrushsize, setsize=setbrushsize, clear=donothing, get=getbrushbackuppixel, put=putbrushpixel},
{getsize=getpicturesize, setsize=setpicturesize, clear=clearpicture, get=getbackuppixel, put=putpicturepixel},
{getsize=getbrushsize, setsize=donothing, clear=donothing, get=getbrushbackuppixel, put=putpicturepixel}
}
trg = func[target]
 
--
function bilinear(ox,oy,w,h,func,mode)
local xp1,xp2,yp1,yp2,r1,r2,r3,r4,g1,g2,g3,g4,b1,b2,b3,b4,r,g,b, c1,c2,c3,c4,pal,adjx,adjy
xp2 = ox - math.floor(ox)
yp2 = oy - math.floor(oy)
 
if mode == 1 then -- Cosinus curve (rather than linear), slightly sharper result (probably same as Photoshop)
xp2 = 1 - (math.cos(xp2 * math.pi) + 1)/2
yp2 = 1 - (math.cos(yp2 * math.pi) + 1)/2
end
 
xp1 = 1 - xp2
yp1 = 1 - yp2
 
c1 = func(math.floor(ox),math.floor(oy));
c2 = func(math.ceil(ox),math.floor(oy));
c3 = func(math.floor(ox),math.ceil(oy));
c4 = func(math.ceil(ox),math.ceil(oy));
 
r1,g1,b1 = getcolor(c1);
r2,g2,b2 = getcolor(c2);
r3,g3,b3 = getcolor(c3);
r4,g4,b4 = getcolor(c4);
pal = {{r1,g1,b1,c1},{r2,g2,b2,c2},{r3,g3,b3,c3},{r4,g4,b4,c4}} -- for SpriteMode ColorMatching
 
r = (r1*xp1 + r2*xp2)*yp1 + (r3*xp1 + r4*xp2)*yp2;
g = (g1*xp1 + g2*xp2)*yp1 + (g3*xp1 + g4*xp2)*yp2;
b = (b1*xp1 + b2*xp2)*yp1 + (b3*xp1 + b4*xp2)*yp2;
 
return r,g,b, pal
end
--
 
f = db.rotationFrac
w,h = trg.getsize()
hub_x = w / 2 - 0.5 -- Rotates 90,180 perfectly, not 45
hub_y = h / 2 - 0.5
--hub_x = w / 2
--hub_y = h / 2
x1,y1 = f (-rot,hub_x,hub_y,0,0) -- Rot is negative coz we read destination and write to source
x2,y2 = f (-rot,hub_x,hub_y,w-1,0)
x3,y3 = f (-rot,hub_x,hub_y,0,h-1)
x4,y4 = f (-rot,hub_x,hub_y,w-1,h-1)
dX = (x2 - x1) / w
dY = (y2 - y1) / w
dXs = (x4 - x2) / h
dYs = (y3 - y1) / h
 
adjx,adjy = 0,0
ox,oy = 0,0
if resize == 1 then
mx = math.ceil(math.max(math.abs(x1-hub_x),math.abs(x3-hub_x))) * 2 + 2
my = math.ceil(math.max(math.abs(y1-hub_y),math.abs(y3-hub_y))) * 2 + 2
if target == 3 then -- Center gfx at Brush-to-Picture
adjx = -mx/2
adjy = -my/2
end
ox = (mx - w) / 2
oy = (my - h) / 2
trg.setsize(mx,my)
end
 
trg.clear(0)
 
for y = -oy, h-1+oy, 1 do
RE,GE,BE = 0,0,0
for x = -ox, w-1+ox, 1 do
xp = x1 + dX * x + dXs * y
yp = y1 + dY * x + dYs * y
 
if mode == 2 or mode == 3 then
r,g,b,pal = bilinear(xp,yp,w,h,trg.get, mode_co)
if spritemode == 1 then
c = db.getBestPalMatchHYBRID({r+RE,g+GE,b+BE},pal,0.65,true) -- Brightness do very little in general with 4 set colors
else c = matchcolor2(r+RE,g+GE,b+BE)
end
else c = trg.get(xp,yp)
end
 
--rn,gn,bn = getcolor(c)
--RE = (r - rn)*0.5
--GE = (g - gn)*0.5
--BE = (b - bn)*0.5
 
trg.put(x+ox+xoffset+adjx,y+oy+yoffset+adjy, c)
end
if update == 1 then
statusmessage("Working... %"..math.floor(((y+oy) / (h-1+2*oy))*100))
updatescreen(); if (waitbreak(0)==1) then return; end
end
end
 
end; -- doRotation
 
-------------------------------------------------------------------------------
 
--
-- PARTICLE v1.0
--
-- Draw Sphere or Disc to any target with gradients that may fade to background
--
-- type: "sphere" - volmetric planet-like disc
-- "disc" - plain disc
-- mode: "blend" - mix graphics with background color
-- "add" - add graphics to background color
-- wd,ht: - Max Width/Height of drawing area, i.e. screen size (needed if drawing to an array-buffer)
-- sx,sy: - drawing coordinates (center)
-- xrad,yrad: - x & y radii
-- rgba1: - rgb+alpha array of center color: {r,g,b,a}, alpha is 0..1 where 1 is no transparency, Extreme rgb-values allowed
-- rgba2: - rgb+alpha array of edge color: {r,g,b,a}, alpha is 0..1 where 1 is no transparency, Extreme rgb-values allowed
-- update_flag: - Display rendering option (and add break feature)
-- f_get: - Get pixel function: use getpicturepixel if reading from image (set null for image default)
-- f_put: - Put pixel function: use putpicturepixel if drawing to image (set null for image default)
-- f_recur: - Optional custom control-function for recursion (set null if not used)
-- recur_count - Recursion depth counter, for use in combination with a custom function (f_recur), 0 as default
--
-- Ex: particle("sphere","add", w,h, w/2,h/2, 40,40, {500,400,255, 0.8},{0,-150,-175, 0.0}, true, null, null, null, 0)
--
function db.particle(type,mode,wd,ht,sx,sy,xrad,yrad,rgba1,rgba2, update_flag, f_get, f_put, f_recur, recur_count)
 
local x,y,rev,dix,diy,r3,g3,b3,px,py,alpha,ralpha,add,q,rgb,rgb1,rgb2,rgb3,n,def_get,def_put
 
function def_get(x,y)
local r,g,b
r,g,b = getcolor(getpicturepixel(x,y));
return {r,g,b}
end
function def_put(x,y,r,g,b) putpicturepixel(x,y, matchcolor2(r,g,b,0.65)); end
if f_get == null then f_get = def_get; end
if f_put == null then f_put = def_put; end
 
q = {[true] = 1, [false] = 0}
 
rgb,rgb1,rgb2 = {},{},{}
 
if mode == 'blend' then
add = 1
end
 
if mode == 'add' then
add = 0
end
 
dix = xrad*2
diy = yrad*2
 
for y = 0, diy, 1 do
py = sy+y-yrad; oy = y / diy;
if (py >= 0 and py < ht) then
 
for x = 0, dix, 1 do
px = sx+x-xrad; ox = x / dix;
if (px >= 0 and px < wd) then
 
if type == 'sphere' then -- Sphere
a = math.sqrt(math.max(0,0.25 - ((0.5-ox)^2+(0.5-oy)^2))) * 2
end
if type == 'disc' then -- Disc
a = 1-math.sqrt((0.5-ox)^2+(0.5-oy)^2)*2
end
 
if a>0 then
 
rev = 1-a
rgb3 = f_get(px,py)
alpha = rgba1[4] * a + rgba2[4] * rev
ralpha = 1 - alpha * add
 
for n = 1, 3, 1 do
rgb1[n] = q[rgba1[n]==-1]*rgb3[n] + q[rgba1[n]~=-1]*rgba1[n] -- Fade from background?
rgb2[n] = q[rgba2[n]==-1]*rgb3[n] + q[rgba2[n]~=-1]*rgba2[n] -- Fade to background?
rgb[n] = (rgb1[n] * a + rgb2[n] * rev) * alpha + rgb3[n] * ralpha
end
 
f_put(px, py, rgb[1],rgb[2],rgb[3]);
end
 
end -- if x is good
end -- x
if update_flag then updatescreen(); if (waitbreak(0)==1) then return; end; end
end -- if y is good
end -- y
 
if f_recur ~= null then -- recursion
f_recur(type,mode,wd,ht,sx,sy,xrad,yrad,rgba1,rgba2, update_flag, f_get, f_put, f_recur, recur_count);
updatescreen(); if (waitbreak(0)==1) then return; end;
end
 
end
-- eof PARTICLE
 
 
--
-- MedianCut a larger palette-list from a MathScene to produce a high-quality BriSorted palette for the final render/colormatching
--
function db.makeSamplePal(w,h,colors,frend)
local n,x,y,r,g,b,pal
n,pal = 0,{}
for y = 0, h, math.ceil(h/63) do
for x = 0, w, math.ceil(w/63) do
r,g,b = frend(x,y,w,h)
n = n+1
r,g,b = db.rgbcapInt(r,g,b,255,0)
pal[n] = {r,g,b,0}
end;end
return db.fixPalette(db.medianCut(pal, colors, true, false, {0.26,0.55,0.19}, 8, 0),1) -- pal, cols, qual, quant, weights, bits, quantpower
end
--
 
--
-- Backdrop/Gradient Render (May be written to a matrix for rendering with db.fsrender)
--
function db.backdrop(p0,p1,p2,p3,fput,ip_mode) -- points:{x,y,r,g,b}, IpMode "linear" is default
 
local x,y,ox,oy,xr,yr,r,g,b,ax,ay,w,h
 
ax,ay = p0[1],p0[2]
 
w = p1[1] - p0[1]
h = p2[2] - p0[2]
 
for y = 0, h, 1 do -- +1 to fill screen with FS-render
 
oy = y/h
if ip_mode == "cosine" then oy = 1 - (math.cos(oy * math.pi) + 1)/2; end
yr = 1 - oy
 
for x = 0, w, 1 do
 
ox = x/w
if ip_mode == "cosine" then ox = 1 - (math.cos(ox * math.pi) + 1)/2; end
xr = 1 - ox
 
r = (p0[3]*xr + p1[3]*ox)*yr + (p2[3]*xr + p3[3]*ox)*oy;
g = (p0[4]*xr + p1[4]*ox)*yr + (p2[4]*xr + p3[4]*ox)*oy;
b = (p0[5]*xr + p1[5]*ox)*yr + (p2[5]*xr + p3[5]*ox)*oy;
 
fput(x+ax,y+ay,r,g,b)
 
end;end
 
end
-- eof backdrop
 
 
 
--
-- SPLINES --
--
function db.splinePoint(x0,y0,x1,y1,x2,y2,points,point)
local x,y,sx1,sy1,sx2,sy2,f
 
f = point * 1 / points
 
sx1 = x0*(1-f) + x1*f
sy1 = y0*(1-f) + y1*f
 
sx2 = x1*(1-f) + x2*f
sy2 = y1*(1-f) + y2*f
 
x = sx1 * (1-f) + sx2 * f
y = sy1 * (1-f) + sy2 * f
 
return x,y
end
--
 
 
-- zx = 2*x1 - (x0+x2)/2
--
function db.drawSplineSegment(x0,y0,x1,y1,x2,y2,x3,y3,points,col) -- Does spline segment p1-p2
local n,x,y,sx1,sy1,sx2,sy2,mid,zx1,zy1,zx2,zy2,fx,fy
mid = math.floor(points / 2)
-- Extended Bezier points
zx1 = 2*x1 - (x0+x2)/2
zy1 = 2*y1 - (y0+y2)/2
zx2 = 2*x2 - (x1+x3)/2
zy2 = 2*y2 - (y1+y3)/2
 
fx,fy = x1,y1 -- Segment to be drawn (0),1 - 2,(3)
for n = 0, mid, 1 do
 
f = n * 1 / points * 2
 
sx1,sy1 = db.splinePoint(x0,y0,zx1,zy1,x2,y2,mid*2, mid + n)
sx2,sy2 = db.splinePoint(x1,y1,zx2,zy2,x3,y3,mid*2, n)
 
x = sx1 * (1-f) + sx2 * f
y = sy1 * (1-f) + sy2 * f
 
--putpicturepixel(x,y,col)
db.line(fx,fy,x,y,col)
fx,fy = x,y
 
end
 
end
--
 
-- eof Splines
/data/common/media/grafx2/scripts/samples_2.4/libs/memory.lua
0,0 → 1,138
-- Persistence library:
-- Memorize data for current function
-- memory.save(tab) and tab=memory.load()
--
-- The data will be stored in file called
-- <calling_function_name>.dat
-- in the lua directory
--
-- Example 1:
--
-- -- Load initial values or set defaults
-- arg = memory.load({picX=320,picY=200,scale=0})
-- -- Run an inputbox
-- OK,arg.picX,arg.picY,arg.scale = inputbox("Image Size")",
-- "Width", arg.picX, 1,2048,0,
-- "Height", arg.picY, 1,2048,0,
-- "Scale", arg.scale, 0,1,0);
-- if OK == true then
-- -- Save the selected values
-- memory.save(arg)
-- end
 
-- Example 2:
--
-- -- Load initial values or set defaults
-- arg = memory.load({x=320,y=200,scale=0})
-- picX=arg.x
-- picY=arg.y
-- scale=arg.scale
-- -- Run an inputbox
-- OK,picX,picY,scale = inputbox("Image Size")",
-- "Width", picX, 1,2048,0,
-- "Height", picY, 1,2048,0,
-- "Scale", scale, 0,1,0);
-- if OK == true then
-- -- Save the selected values
-- memory.save({x=picX,y=picY,scale=scale})
-- end
 
memory =
{
serialize = function(o)
if type(o) == "number" then
return tostring(o)
elseif type(o) == "string" then
return string.format("%q", o)
--elseif type(o) == "table" then
-- io.write("{\n")
-- for k,v in pairs(o) do
-- io.write(" ", k, " = ")
-- memory.serialize(v)
-- io.write(",\n")
-- end
-- io.write("}\n")
else
error("cannot serialize a " .. type(o))
end
end;
-- Return a string identifying the calling function.
-- Pass 1 for parent, 2 for grandparent etc.
callername = function(level)
local w
local last_slash
local info = debug.getinfo(level+1,"Sn")
local caller=tostring(info.name)
-- Function name if possible
if (caller~="nil") then
return caller
end
-- Otherwise, get file name, without extension
-- Get part after directory name
last_slash=0
while true do
local pos = string.find(info.source, "/", last_slash+1)
if (pos==nil) then break end
last_slash=pos
end
while true do
local pos = string.find(info.source, "\\", last_slash+1)
if (pos==nil) then break end
last_slash=pos
end
caller=string.sub(info.source, last_slash+1)
-- Remove file extension
if (string.sub(caller,-4, -1)==".lua") then
caller=string.sub(caller, 1, -5)
end
return caller
end;
-- Memorize some parameters.
save = function(o)
local caller=memory.callername(2)
--for k, v in pairs(o) do
-- messagebox(tostring(k))
-- messagebox(tostring(v))
--end
local f, e = io.open(caller..".dat", "w");
if (f ~= nil) then
f:write("Entry {\n")
for k, v in pairs(o) do
if (type(v)=="number") then
f:write(" "..k.."="..memory["serialize"](v)..",\n")
end
end
f:write("}\n")
f:close()
end
end;
-- Recover some saved parameters.
load = function(o)
local caller=memory.callername(2)
local i
 
function Entry (b)
-- Adds (or replaces) values in arg with those from b
for k, v in pairs(b) do
o[k]=v
end
end
local f = (loadfile(caller..".dat"))
if (f ~= nil) then
f()
end
 
return o
end;
 
}
 
return memory
/data/common/media/grafx2/scripts/samples_2.4/palette/Desaturate.lua
0,0 → 1,40
--PALETTE Adjust: Desaturate v1.1
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
 
-- Copyright 2010 Richard Fhager
--
-- 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; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
-- This script was adopted from Evalion, a Javascript codecrafting/imageprocessing project
-- http://goto.glocalnet.net/richard_fhager/evalion/evalion.html
 
 
-- Note: Negative values will work as INCREASED saturation, but I'm not sure if this function is 100% correct
 
 
--percent = 25
 
OK,percent = inputbox("Desaturate Palette","Percent %", 25, 0,100,0);
 
--
function desaturate(percent,r,g,b) -- V1.0 by Richard Fhager
p = percent / 100
a = (math.min(math.max(r,g,b),255) + math.max(math.min(r,g,b),0)) * 0.5 * p
r = r + (a-r*p)
g = g + (a-g*p)
b = b + (a-b*p)
return r,g,b
end
--
 
if OK == true then
 
for c = 0, 255, 1 do
setcolor(c, desaturate(percent,getcolor(c)))
end
 
end
/data/common/media/grafx2/scripts/samples_2.4/palette/ExpandColors.lua
0,0 → 1,171
--PALETTE: Expand Colors v1.0
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
-- Email: dawnbringer@hem.utfors.se
-- MSN: annassar@hotmail.com
--
-- Copyright 2010 Richard Fhager
--
-- 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; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
 
-- Continously fill the greatest void in the area of the color-cube enclosed by (or along ramps of) initial colors
-- This algorithm will create lines of allowed colors (all ranges) in 3d colorspace and the pick
-- new colors from the most void areas (on any line). Almost like a Median-cut in reverse.
--
-- Rather than filling the colorcube symmetrically it adds intermediate colors to the existing ones.
--
-- Running this script on the C64 16-color palette might be educational
--
--
-- Source cols#, Expand to #,
-- Ex: 15-31 means that palette colors 0-15 is expanded to 16 new colors placed at slots 16-31
--
-- Spread mode: OFF - New colors will conform to the contrast & saturation of original colors
-- (new colors will stay on the ramps possible from the original colors)
--
-- ON - New colors will expand their variance by each new addition (mostly notable when adding many new colors)
-- Will add range lines/ramps to all new colors from old ones, but keep within max/min values of the
-- original colors. 15-bit mode will dampen the spread towards extreme colors (if starting with low contrast)
--
-- 15-bit colors: Higher color-resolution, 32768 possible colors rather than the 4096 of 12bit. Slower but perhaps better.
--
 
SHADES = 16 -- Going 24bit will probably be too slow and steal too much memory, so start with 12bit (4096 colors) for now
 
ini = 0
exp = 255
 
OK,ini,exp,linemode,fbit = inputbox("Expand Colors (0-255):",
"Source Cols #: 1-254", 15, 1,254,0,
"Expand to #: 2-255", 31, 2,255,0,
"Spread mode", 0, 0,1,0,
"15-bit colors (slow)", 0, 0,1,0
);
 
if (fbit == 1) then SHADES = 32; end
 
 
 
function initColorCube(sha)
ary = {}
for z = 0, sha-1, 1 do
ary[z+1] = {}
for y = 0, sha-1, 1 do
ary[z+1][y+1] = {}
for x = 0, sha-1, 1 do
ary[z+1][y+1][x+1] = {false,0}
end
end
end
return ary
end
 
-- Gravity model (think of colors as stars of equal mass/brightness in a 3d space)
function addColor2Cube(cube,sha,r,g,b)
star = 1000000
fade = 1000
 
cube[r+1][g+1][b+1] = {false,star}
 
for z = 0, sha-1, 1 do
for y = 0, sha-1, 1 do
for x = 0, sha-1, 1 do
 
d = fade / ( (x-b)^2 + (y-g)^2 + (z-r)^2 )
 
cube[z+1][y+1][x+1][2] = cube[z+1][y+1][x+1][2] + d
 
end;end;end
end
 
 
-- Create new allowed colorlines in colorspace (ramps from which colors can be picked)
function enableRangeColorsInCube(cube,sha,r1,g1,b1,r2,g2,b2)
 
local div,r,g,b
div = 256 / sha
rs = (r2 - r1) / sha / div
gs = (g2 - g1) / sha / div
bs = (b2 - b1) / sha / div
 
for n = 0, sha-1, 1 do
 
r = math.floor(r1/div + rs * n)
g = math.floor(g1/div + gs * n)
b = math.floor(b1/div + bs * n)
 
cube[r+1][g+1][b+1][1] = true
 
end
end
 
 
function findVoid(cube,sha)
weakest = 999999999999
weak_i = {-1,-1,-1}
for z = 0, sha-1, 1 do
for y = 0, sha-1, 1 do
for x = 0, sha-1, 1 do
c = cube[z+1][y+1][x+1]
if c[1] == true then
w = c[2]
if w <= weakest then weakest = w; weak_i = {z,y,x}; end
end
end;end;end
return weak_i[1],weak_i[2],weak_i[3]
end
 
--
 
if OK == true then
 
cube = initColorCube(SHADES)
 
-- Define allowed colorspace
for y = 0, ini-1, 1 do
r1,g1,b1 = getcolor(y)
for x = y+1, ini, 1 do
r2,g2,b2 = getcolor(x)
enableRangeColorsInCube(cube,SHADES,r1,g1,b1,r2,g2,b2)
end
end
 
div = 256 / SHADES
 
-- Fill cube with initial colors
for n = 0, ini, 1 do
r,g,b = getcolor(n)
addColor2Cube(cube,SHADES,math.floor(r/div),math.floor(g/div),math.floor(b/div))
end
 
 
for n = ini+1, exp, 1 do
r,g,b = findVoid(cube,SHADES)
 
if (r == -1) then messagebox("Report:","No more colors can be found, exit at "..n); break; end
 
mult = 255 / (SHADES - 1)
setcolor(n, r*mult,g*mult,b*mult)
 
if linemode == 1 then
-- Add lines from new color to all old
for x = 0, n-1, 1 do
r2,g2,b2 = getcolor(x)
enableRangeColorsInCube(cube,SHADES,r*mult,g*mult,b*mult,r2,g2,b2) -- uses 24bit values rgb
end
end
addColor2Cube(cube,SHADES,r,g,b) -- rgb is in 'shade' format here
end
 
end
 
 
 
/data/common/media/grafx2/scripts/samples_2.4/palette/FillColorCube.lua
0,0 → 1,105
--PALETTE: Fill ColorCube voids v1.0
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
-- Email: dawnbringer@hem.utfors.se
-- MSN: annassar@hotmail.com
--
-- Copyright 2010 Richard Fhager
--
-- 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; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
--
-- Create a palette by continously filling the greatest void in the RGB color-cube
--
 
 
SHADES = 16 -- Going 24bit will probably be too slow and steal too much memory, so we're 12bit (4096 colors) for now
 
ini = 0
exp = 255
 
OK,ini,exp = inputbox("Fill Palette Color voids",
"From/Keep #: 0-254", 0, 0,254,0,
"Replace to #: 1-255", 31, 1,255,0
);
 
 
function initColorCube(sha)
ary = {}
for z = 0, sha-1, 1 do
ary[z+1] = {}
for y = 0, sha-1, 1 do
ary[z+1][y+1] = {}
end
end
return ary
end
 
 
function addColor2Cube(cube,sha,r,g,b) -- Gravity model
star = 1000000
fade = 1000
 
cube[r+1][g+1][b+1] = star
for z = 0, sha-1, 1 do
for y = 0, sha-1, 1 do
for x = 0, sha-1, 1 do
 
d = fade / ( (x-b)^2 + (y-g)^2 + (z-r)^2 )
 
if cube[z+1][y+1][x+1] ~= nil then
cube[z+1][y+1][x+1] = cube[z+1][y+1][x+1] + d
else
cube[z+1][y+1][x+1] = d
end
 
end;end;end
end
 
 
function findVoid(cube,sha)
weakest = 999999999999
weak_i = {-1,-1,-1}
for z = 0, sha-1, 1 do
for y = 0, sha-1, 1 do
for x = 0, sha-1, 1 do
w = cube[z+1][y+1][x+1]
if w <= weakest then weakest = w; weak_i = {z,y,x}; end
end;end;end
return weak_i[1],weak_i[2],weak_i[3]
end
 
--
 
if OK == true then
 
cube = initColorCube(SHADES)
-- Fill cube with initial colors
for n = 0, ini-1, 1 do
r,g,b = getcolor(n)
div = SHADES
addColor2Cube(cube,SHADES,math.floor(r/div),math.floor(g/div),math.floor(b/div))
end
 
if ini == 0 then -- With no inital color, some inital data must be added to the colorcube.
addColor2Cube(cube,SHADES,0,0,0)
setcolor(0, 0,0,0)
ini = ini + 1
end
 
for n = ini, exp, 1 do
r,g,b = findVoid(cube,SHADES)
mult = 255 / (SHADES - 1)
setcolor(n, r*mult,g*mult,b*mult)
addColor2Cube(cube,SHADES,r,g,b)
end
 
end
 
 
 
/data/common/media/grafx2/scripts/samples_2.4/palette/InvertedRGB.lua
0,0 → 1,27
--PALETTE Modify: Inverted RGB
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
 
-- Copyright 2010 Richard Fhager
--
-- 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; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
-- This script was adopted from Evalion, a Javascript codecrafting/imageprocessing project
-- http://goto.glocalnet.net/richard_fhager/evalion/evalion.html
 
 
 
for c = 0, 255, 1 do
 
r,g,b = getcolor(c)
r2 = (g+b)/2
g2 = (r+b)/2
b2 = (r+g)/2
 
setcolor(c, r2,g2,b2)
 
end
/data/common/media/grafx2/scripts/samples_2.4/palette/Set3bit.lua
0,0 → 1,39
--PALETTE Set: 3 Bit (8 Primaries)
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
 
-- Copyright 2010 Richard Fhager
--
-- 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; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
 
-- Generate palette of all colors possible with a given number of shades for each channel
-- 2 shades = 1 bit / channel = 3 bit palette = 2^3 colors = 8 colors
-- 4 shades = 2 bit / channel = 6 bit palette = 2^6 colors = 64 colors
 
-- Channel shades (shades = 2 ^ bit-depth)
shades = 2
 
mult = 255 / (shades-1)
 
 
colors = {}
col = 0
for r = 0, shades-1, 1 do
for g = 0, shades-1, 1 do
for b = 0, shades-1, 1 do
col = col + 1
colors[col] = { r*mult, g*mult, b*mult }
end
end
end
 
 
for c = 1, #colors, 1 do
 
setcolor(c-1,colors[c][1],colors[c][2],colors[c][3])
 
end
/data/common/media/grafx2/scripts/samples_2.4/palette/Set6bit.lua
0,0 → 1,39
--PALETTE Set: Full 6 Bit (64 colors)
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
 
-- Copyright 2010 Richard Fhager
--
-- 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; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
 
-- Generate palette of all colors possible with a given number of shades for each channel
-- 2 shades = 1 bit / channel = 3 bit palette = 2^3 colors = 8 colors
-- 4 shades = 2 bit / channel = 6 bit palette = 2^6 colors = 64 colors
 
-- Channel shades (shades = 2 ^ bit-depth)
shades = 4
 
mult = 255 / (shades-1)
 
 
colors = {}
col = 0
for r = 0, shades-1, 1 do
for g = 0, shades-1, 1 do
for b = 0, shades-1, 1 do
col = col + 1
colors[col] = { r*mult, g*mult, b*mult }
end
end
end
 
 
for c = 1, #colors, 1 do
 
setcolor(c-1,colors[c][1],colors[c][2],colors[c][3])
 
end
/data/common/media/grafx2/scripts/samples_2.4/palette/SetC64Palette.lua
0,0 → 1,50
--PALETTE Set: C64 Palette (16 colors)
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
 
-- Copyright 2010 Richard Fhager
--
-- 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; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
 
OK,clean = inputbox("C64 Palette:", "Remove old palette", 0, 0,1,0
);
 
 
 
colors = {{0, 0, 0}, -- 0 Black
{62, 49,162}, -- 1 D.Blue
{87, 66, 0}, -- 2 Brown
{140, 62, 52}, -- 3 D.Red
{84, 84, 84}, -- 4 D.Grey
{141, 72,179}, -- 5 Purple
{144, 95, 37}, -- 6 Orange
{124,112,218}, -- 7 B.Blue
{128,128,128}, -- 8 Grey
{104,169, 65}, -- 9 Green
{187,119,109}, -- 10 B.Red
{122,191,199}, -- 11 Cyan
{171,171,171}, -- 12 B.Grey
{208,220,113}, -- 13 Yellow
{172,234,136}, -- 14 B.Green
{255,255,255} -- 15 White
}
 
 
if OK == true then
 
for c = 1, #colors, 1 do
setcolor(c-1,colors[c][1],colors[c][2],colors[c][3])
end
 
 
if clean == 1 then
for c = #colors+1, 256, 1 do
setcolor(c-1,0,0,0)
end
end
 
end
/data/common/media/grafx2/scripts/samples_2.4/palette/ShiftHue.lua
0,0 → 1,55
--PALETTE Adjust: Shift Hue v0.9
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
 
-- Copyright 2010 Richard Fhager
--
-- 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; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
-- This script was adopted from Evalion, a Javascript codecrafting/imageprocessing project
-- http://goto.glocalnet.net/richard_fhager/evalion/evalion.html
 
 
--Shift_degrees = 45
 
OK,Shift_degrees = inputbox("Shift Hue v0.9","Degrees", 45, 0,360,3);
 
 
--
function shiftHUE(r,g,b,deg) -- V1.3 R.Fhager 2007, adopted from Evalion
local c,h,mi,mx,d,s,p,i,f,q,t
c = {g,b,r}
mi = math.min(r,g,b)
mx = math.max(r,g,b); v = mx;
d = mx - mi;
s = 0; if mx ~= 0 then s = d/mx; end
p = 1; if g ~= mx then p = 2; if b ~= mx then p = 0; end; end
if s~=0 then
h=(deg/60+(6+p*2+(c[1+p]-c[1+(p+1)%3])/d))%6;
i=math.floor(h);
f=h-i;
p=v*(1-s);
q=v*(1-s*f);
t=v*(1-s*(1-f));
c={v,q,p,p,t,v}
r = c[1+i]
g = c[1+(i+4)%6]
b = c[1+(i+2)%6]
end
 
return r,g,b
end
--
 
if OK == true then
 
for c = 0, 255, 1 do
r,g,b = getcolor(c)
setcolor(c, shiftHUE(r,g,b,Shift_degrees))
end
 
end
/data/common/media/grafx2/scripts/samples_2.4/picture/CellColourReducer.lua
0,0 → 1,37
-- cell colour reducer - jan'11, from Paulo Silva, with help from people from GrafX2 google group (DawnBringer, Adrien Destugues (PulkoMandy), and Yves Rizoud)
-- 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; version 2 of the License. See <http://www.gnu.org/licenses/>
w,h=getpicturesize()
ok,xcell,ycell=inputbox("Modify cell pixel size","xcell",8,1,16,4,"ycell",8,1,16,4);
if ok==true then
function grayscaleindexed(c)
r,g,b=getcolor(c);return math.floor((b*11+r*30+g*59)/100);end
celcnt={};for n=0,255,1 do celcnt[n+1]=0;end -- Arraycounter must have initial value
for y1=0,h-1,ycell do
for x1=0,w-1,xcell do
for i=0,255,1 do
celcnt[i+1]=0;end
for y2=0,ycell-1,1 do
for x2=0,xcell-1,1 do
x=x1+x2;y=y1+y2;u=getpicturepixel(x,y)
celcnt[u+1]=celcnt[u+1]+(1000*xcell*ycell)+math.random(0,950);end;end
ikattr=0;paattr=0;ikcnt=0;pacnt=0
for i=0,255,1 do
if ikcnt<celcnt[i+1] then ikcnt=celcnt[i+1];ikattr=i;end;end
celcnt[ikattr+1]=0
for i=0,255,1 do
if pacnt<celcnt[i+1] then pacnt=celcnt[i+1];paattr=i;end;end
if grayscaleindexed(ikattr)>grayscaleindexed(paattr) then tmpr=ikattr;ikattr=paattr;paattr=tmpr;end
wmid=math.floor((grayscaleindexed(paattr)+grayscaleindexed(ikattr))/2)
for y2=0,ycell-1,1 do
for x2=0,xcell-1,1 do
x=x1+x2;y=y1+y2;u=getpicturepixel(x,y)
if u==ikattr then
idou=ikattr
elseif u==paattr then
idou=paattr
else
idou=ikattr
if grayscaleindexed(u)>wmid then idou=paattr;end
end
putpicturepixel(x,y,idou)
end;end;end;end;end
/data/common/media/grafx2/scripts/samples_2.4/picture/DrawGridIsometric.lua
0,0 → 1,13
-- Draw isometric grid - Copyright 2010 Paulo Silva
-- 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; version 2 of the License. See <http://www.gnu.org/licenses/>
w,h=getpicturesize();
ok,gsiz,ik=inputbox("draw isometric grid","size",16,0,128,5,"colour",1,0,255,6);
if ok==true then
for y=0,h-1,gsiz do
for x=0,w-1,1 do
putpicturepixel(x,y+(x/2)%gsiz,ik);
end;end
for y=0,h-1,gsiz do
for x=0,w-1,1 do
putpicturepixel(x+((gsiz/2)-1),y+(gsiz-1)-((x/2)%gsiz),ik);
end;end;end
/data/common/media/grafx2/scripts/samples_2.4/picture/DrawGridOrthogonal_RGB.lua
0,0 → 1,14
-- draw grid - rgb (matchcolor) - Copyright 2010 Paulo Silva
-- 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; version 2 of the License. See <http://www.gnu.org/licenses/>
w,h=getpicturesize()
ok,xsiz,ysiz,r,g,b=inputbox("draw grid - rgb (matchcolor)","x size",8,1,64,5,"y size",8,1,64,6,"r",128,0,255,6,"g",128,0,255,6,"b",128,0,255,6);
if ok==true then
c=matchcolor(r,g,b)
for y=0,h-1,1 do
for x=0,w-1,xsiz do
putpicturepixel(x,y,c);
end;end
for y=0,h-1,ysiz do
for x=0,w-1,1 do
putpicturepixel(x,y,c);
end;end;end
/data/common/media/grafx2/scripts/samples_2.4/picture/DrawgridOrthogonal_Index.lua
0,0 → 1,11
-- draw grid - indexed colour - Copyright 2010 Paulo Silva
-- 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; version 2 of the License. See <http://www.gnu.org/licenses/>
w,h=getpicturesize();
ok,xsiz,ysiz,c=inputbox("draw grid - indexed colour)","x size",8,1,64,5,"y size",8,1,64,6,"colour id",0,0,255,6);
if ok==true then
for y=0,h-1,1 do
for x=0,w-1,xsiz do
putpicturepixel(x,y,c);end;end
for y=0,h-1,ysiz do
for x=0,w-1,1 do
putpicturepixel(x,y,c);end;end;end
/data/common/media/grafx2/scripts/samples_2.4/picture/GlassGridFilter.lua
0,0 → 1,12
-- Glass grid filter - Copyright 2010 Paulo Silva
-- 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; version 2 of the License. See <http://www.gnu.org/licenses/>
w,h=getpicturesize();
ok,xsiz,ysiz=inputbox("message","xsize",8,0,64,5,"ysize",8,0,64,6);
if ok==true then
for y1=0,h-1,xsiz do
for x1=0,w-1,ysiz do
for y2=0,(ysiz/2)-1,1 do
for x2=0,xsiz-1,1 do
c1=getpicturepixel(x1+x2,y1+y2);c2=getpicturepixel(x1+(xsiz-1)-x2,y1+(ysiz-1)-y2)
putpicturepixel(x1+x2,y1+y2,c2);putpicturepixel(x1+(xsiz-1)-x2,y1+(ysiz-1)-y2,c1)
end;end;end;end;end
/data/common/media/grafx2/scripts/samples_2.4/picture/PaletteToPicture.lua
0,0 → 1,11
-- palette to picture - Copyright 2010 Paulo Silva
-- 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; version 2 of the License. See <http://www.gnu.org/licenses/>
w,h=getpicturesize();
ok,xsiz,ysiz=inputbox("palette to picture","x size",8,1,16,5,"y size",8,1,16,6);
if ok==true then
for y1=0,7,1 do
for x1=0,31,1 do
for y2=0,ysiz-1,1 do
for x2=0,xsiz-1,1 do
putpicturepixel(x1*xsiz+x2,y1*ysiz+y2,y1+x1*8)
end;end;end;end;end
/data/common/media/grafx2/scripts/samples_2.4/picture/Pic2isometric.lua
0,0 → 1,87
--PICTURE (part of): 2 Isometric v0.1b
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
-- Email: dawnbringer@hem.utfors.se
-- MSN: annassar@hotmail.com
--
-- Copyright 2010 Richard Fhager
--
-- 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; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
 
-- Color 0 is assumed to be the background
--
 
iso = {{0, 0, 1, 1, 1, 1, 0, 0},
{1, 1, 1, 1, 1, 1, 1, 1},
{2, 2, 1, 1, 1, 1, 3, 3},
{2, 2, 2, 2, 3, 3, 3, 3},
{2, 2, 2, 2, 3, 3, 3, 3},
{2, 2, 2, 2, 3, 3, 3, 3},
{0, 0, 2, 2, 3, 3, 0, 0}}
 
isowidth = 8
isoheight = 7
 
xoff = 0.5
yoff = 0
 
xstep = 4
ystep = 2
zstep = 4
 
-- Part of screen from top-left (4 = 1/4)
xsize = 5
ysize = 4
 
 
w, h = getpicturesize()
 
xo = math.floor(w * xoff)
 
-- just don't render more than can be fittted right now
w = math.floor(w / xsize)
h = math.floor(h / ysize)
 
 
 
for y = 0, h - 1, 1 do
for x = 0, w - 1, 1 do
 
isox = x * xstep - y * xstep
isoy = y * ystep + x * ystep
cb = getbackuppixel(x,y)
 
--
if cb ~= 0 then
 
r,g,b = getbackupcolor(cb);
c1 = matchcolor(r,g,b);
c2 = matchcolor(r+64, g+64, b+64);
c3 = matchcolor(r-64, g-64, b-64);
cols = {0,c1,c2,c3}
 
for iy = 1, isoheight, 1 do
for ix = 1, isowidth, 1 do
i = iso[iy][ix]
c = cols[i+1]
if i ~= 0 then putpicturepixel(xo + isox+ix-1, isoy+iy-1, c); end
end
end
 
end
--
 
end
end
 
 
 
 
/data/common/media/grafx2/scripts/samples_2.4/picture/Rainbow-Dark2Bright.lua
0,0 → 1,36
--PICTURE: Rainbow - Dark to Bright v1.1
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
-- Email: dawnbringer@hem.utfors.se
-- MSN: annassar@hotmail.com
--
 
 
--dofile("dawnbringer_lib.lua")
run("../libs/dawnbringer_lib.lua")
--> db.shiftHUE(r,g,b, deg)
 
w, h = getpicturesize()
 
for y = 0, h - 1, 1 do
for x = 0, w - 1, 1 do
 
-- Fractionalize image dimensions
ox = x / w;
oy = y / h;
 
r = 255 * math.sin(oy * 2)
g = (oy-0.5)*512 * oy
b = (oy-0.5)*512 * oy
 
r, g, b = db.shiftHUE(r,g,b,ox * 360);
c = matchcolor(r,g,b)
putpicturepixel(x, y, c);
 
end
updatescreen(); if (waitbreak(0)==1) then return; end
end
 
 
/data/common/media/grafx2/scripts/samples_2.4/picture/RemapImage2RGB.lua
0,0 → 1,50
--SCENE: Remap pic to RGB, diag.dith
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
 
-- Copyright 2010 Richard Fhager
--
-- 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; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
-- Set Palette (to a predefined one)
 
colors = {{ 0, 0, 0},
{255, 0, 0},
{ 0,255, 0},
{ 0, 0,255}
}
 
 
chm = {1,0,0}
 
for c = 1, #colors, 1 do
setcolor(c-1,colors[c][1],colors[c][2],colors[c][3])
end
 
for c = #colors, 255, 1 do
setcolor(c,0,0,0)
end
 
 
 
w, h = getpicturesize()
 
for y = 0, h - 1, 1 do
 
for x = 0, w - 1, 1 do
r,g,b = getbackupcolor(getbackuppixel(x,y));
 
rn = r * chm[1+(y+0+x)%3]
gn = g * chm[1+(y+1+x)%3]
bn = b * chm[1+(y+2+x)%3]
 
n = matchcolor(rn,gn,bn);
 
putpicturepixel(x, y, n);
 
end
end
/data/common/media/grafx2/scripts/samples_2.4/picture/RemapImage2RGB_ed.lua
0,0 → 1,69
--SCENE: Remap pic 2 RGB, 1lineED-dith. (Same line simple error-diffusion dither)
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
 
-- Copyright 2010 Richard Fhager
--
-- 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; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
 
power = 0.615
 
c1 = 0.8 -- Error weight (white is green)
c2 = 0.2 -- RGB weight (white is r+g+b)
 
-- Set Palette (to a predefined one)
 
colors = {{ 0, 0, 0},
{255, 0, 0},
{ 0,255, 0},
{ 0, 0,255}
}
 
 
chm = {1,0,0}
 
for c = 1, #colors, 1 do
setcolor(c-1,colors[c][1],colors[c][2],colors[c][3])
end
 
for c = #colors, 255, 1 do
setcolor(c,0,0,0)
end
 
 
 
w, h = getpicturesize()
 
for y = 0, h - 1, 1 do
 
re = 0
ge = 0
be = 0
 
for x = (y%2), w - 1, 1 do
r,g,b = getbackupcolor(getbackuppixel(x,y));
 
rn = re * c1 + r * chm[1+(y+0+x)%3] * c2
gn = ge * c1 + g * chm[1+(y+1+x)%3] * c2
bn = be * c1 + b * chm[1+(y+2+x)%3] * c2
 
n = matchcolor(rn,gn,bn);
 
putpicturepixel(x, y, n);
 
rn,gn,bn = getcolor(getpicturepixel(x,y));
re = (re + (r - rn)) * power
ge = (ge + (g - gn)) * power
be = (be + (b - bn)) * power
 
 
end
end
/data/common/media/grafx2/scripts/samples_2.4/picture/RemapImageTo3bitPal.lua
0,0 → 1,80
--SCENE: Remap pic to 3bit, LineEDdith. (Same line simple error-diffusion dither)
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
 
-- Copyright 2010 Richard Fhager
--
-- 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; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
--
-- Just a demonstration.
--
 
 
 
power = 0.6
 
-- Channel shades (shades = 2 ^ bit-depth)
shades = 2
 
mult = 255 / (shades-1)
 
 
colors = {}
col = 0
for r = 0, shades-1, 1 do
for g = 0, shades-1, 1 do
for b = 0, shades-1, 1 do
col = col + 1
colors[col] = { r*mult, g*mult, b*mult }
end
end
end
 
 
for c = 1, #colors, 1 do
 
setcolor(c-1,colors[c][1],colors[c][2],colors[c][3])
 
end
 
 
for c = #colors, 255, 1 do
setcolor(c,0,0,0)
end
 
 
 
w, h = getpicturesize()
 
for y = 0, h - 1, 1 do
 
re = 0
ge = 0
be = 0
 
for x = (y%2), w - 1, 1 do
r,g,b = getbackupcolor(getbackuppixel(x,y));
 
rn = re + r
gn = ge + g
bn = be + b
 
n = matchcolor(rn,gn,bn);
 
putpicturepixel(x, y, n);
 
rn,gn,bn = getcolor(getpicturepixel(x,y));
re = (re + (r - rn)) * power
ge = (ge + (g - gn)) * power
be = (be + (b - bn)) * power
 
end
end
/data/common/media/grafx2/scripts/samples_2.4/picture/Tiler.lua
0,0 → 1,112
--Picture Tiler by Adrien Destugues
--Extract unique tiles from the spare page
--to the main one. Main page is erased.
--
-- Copyright 2011 Adrien Destugues <pulkomandy@pulkomandy.ath.cx>
--
-- 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; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
-- Copy palette from spare to main
-- TODO
 
-- Grid size
-- TODO : get it from GrafX2
xgrid = 16;
ygrid = 16;
 
-- picture size
w, h = getpicturesize();
 
-- We may need less if there are duplicates
setsparepicturesize(xgrid, w*h/xgrid);
 
tileid = 0;
 
-- blit part of the spare to picture
function blitpicturetospare(srcx, srcy, dstx, dsty, width, height)
local x,y;
for y = 0, height - 1, 1 do
for x = 0, width - 1, 1 do
putsparepicturepixel(dstx+x, dsty+y, getpicturepixel(srcx + x, srcy + y));
end
end
end
 
function comparesparewithpicture(srcx, srcy, dstx, dsty, width, height)
local x,y,color
for y = 0, height - 1, 1 do
for x = 0, width - 1, 1 do
color = getsparepicturepixel(srcx + x, srcy + y);
if color ~= getpicturepixel(dstx+x, dsty+y) then
-- they are different
return false;
end
end
end
-- they are identical
return true;
end
 
-- compute checksum of a picture area
-- it may not be unique, we use it as a key for an hashmap
function checksum(srcx, srcy, width, height)
local sum,x,y
sum = 0;
for y = 0, height - 1, 1 do
for x = 0, width - 1, 1 do
sum = sum + getpicturepixel(srcx+x, srcy+y);
end
end
 
return sum;
end
 
tilemap = {}
 
-- foreach tile
for y = 0, h-1, ygrid do
for x = 0, w - 1, xgrid do
-- existing one ?
csum = checksum(x,y,xgrid,ygrid);
if tilemap[csum] ~= nil then
-- potential match
-- Find matching tileid
found = false;
for id in pairs(tilemap[csum]) do
-- is it a match ?
if comparesparewithpicture(x,y,0,id*ygrid, xgrid, ygrid) then
-- found it !
tilemap[csum][id] = tilemap[csum][id] + 1;
found = true;
break;
end
end
-- Add tile anyway if needed
if not found then
desty = tileid * ygrid;
blitpicturetospare(x, y, 0, desty, xgrid, ygrid);
 
-- add it to the tilemap
tilemap[csum][tileid] = 1;
-- give it a tile id
tileid = tileid + 1;
end
else
-- Copy to spare
desty = tileid * ygrid;
blitpicturetospare(x, y, 0, desty, xgrid, ygrid);
 
-- add it to the tilemap
tilemap[csum] = {}
tilemap[csum][tileid] = 1;
-- give it a tile id
tileid = tileid + 1;
end
end
end
 
setsparepicturesize(xgrid, (tileid-1)*ygrid)
--updatescreen();
/data/common/media/grafx2/scripts/samples_2.4/picture/XBitColourXpaceFromPalette.lua
0,0 → 1,12
-- Copyright 2010 Paulo Silva
-- 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; version 2 of the License. See <http://www.gnu.org/licenses/>
w,h=getpicturesize();
ok,bitd=inputbox("colourspace from palette","bitdepth:",4,1,8,5);
if ok==true then
bitd3=(2^bitd);bitd8=(2^(math.floor(bitd/2)));bitd9=(2^((math.floor((bitd-1)/2))+1))
for y1=0,(bitd8-1),1 do
for x1=0,(bitd9-1),1 do
for y2=0,(bitd3-1),1 do
for x2=0,(bitd3-1),1 do
putpicturepixel(x1*bitd3+x2,y1*bitd3+y2,matchcolor((y2*255)/(bitd3-1),((y1*8+x1)*255)/(bitd3-1),(x2*255)/(bitd3-1)))
end;end;end;end;end
/data/common/media/grafx2/skins/font_Classic.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/skins/font_DPaint.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/skins/font_Fairlight.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/skins/font_Fun.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/skins/font_Melon.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/skins/font_Seen.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/skins/skin_Aurora.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/skins/skin_Clax2.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/skins/skin_Clax3.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/skins/skin_Clax4.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/skins/skin_DPaint.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/skins/skin_classic.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/skins/skin_modern.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/skins/skin_scenish.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/settings/app_plus.ini
7,6 → 7,7
[Media]
zSea=/kolibrios/media/zsea/zsea,46
FPlay=/kolibrios/media/fplay,40
GrafX2=/kolibrios/grafx2/grafx2,48
 
[3D Tools]
Info3DsPro=/kolibrios/3d/info3ds/info3ds,75
15,8 → 16,9
 
[3D Demos]
3dsHeart=/kolibrios/3d/3dsheart,78
M2View=/kolibrios/3d/m2view/m2view,78
 
[Other]
Calc+=/kolibrios/utils/calcplus,4
Life=/kolibrios/demos/life2,13
fNav=/kolibrios/unils/fNav.kex,45
fNav=/kolibrios/utils/fNav.kex,45