Skip to content

Commit

Permalink
Use a seeded hash for random colours, allowing > 16bpp to use random …
Browse files Browse the repository at this point in the history
…mode. Simplifies regeneration.

implements proposal from #26
  • Loading branch information
bbbradsmith committed Oct 15, 2024
1 parent 94ef7a7 commit 9c2e80c
Showing 1 changed file with 55 additions and 30 deletions.
85 changes: 55 additions & 30 deletions BinxelviewForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using static System.Windows.Forms.VisualStyles.VisualStyleElement.ProgressBar;
using System.Xml.Linq;
using Binxelview.Dialogs;
using System.Security.Policy;

namespace Binxelview
{
Expand Down Expand Up @@ -75,6 +76,7 @@ enum PaletteMode
bool disable_pixel_redraw = false; // used to temporarily block redraws during repeated updates
Font posfont_regular, posfont_bold;
Random random = new Random();
uint random_seed;
int preset_menu_fixed_items;
int main_w, main_h; // used to restore size during split_view switch
int fixed_w, fixed_h;
Expand Down Expand Up @@ -1063,6 +1065,47 @@ unsafe int cubeHelix(long x)
return b | (g << 8) | (r << 16) | unchecked((int)0xFF000000);
}

void randomColorSeed() // reseed the random color generator
{
random_seed =
(uint)random.Next(0x00010000) ^
(((uint)random.Next(0x00010000)) << 16);
}

unsafe int randomColorHash(long x)
{
// derived from MurmurHash3 (public domain)
// https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp

const uint C1 = 0xCC9E2D51;
const uint C2 = 0x1B873593;
const uint C3 = 0xE6546B64;
const uint C4 = 0x85EBCA6B;
const uint C5 = 0xC2B2AE35;

uint h = random_seed;

// one 32-bit iteration
uint k = (uint)x;
k *= C1;
k = (k << 15) | (k >> 17);
k *= C2;
h ^= k;
h = (h << 13) | (h >> 19);
h = h * 5 + C3;

// finalization mix
h ^= h >> 16;
h *= C4;
h ^= h >> 13;
h *= C5;
h ^= h >> 16;

// reduce to 24-bit colour
h = h & 0x00FFFFFF;
return (int)h | unchecked((int)0xFF000000);
}

unsafe int autoPaletteRaw(long x) // generated palettes
{
switch (palette_mode)
Expand All @@ -1074,6 +1117,8 @@ unsafe int autoPaletteRaw(long x) // generated palettes
int g = (((ix >> palette_gshift) & palette_gmask) * 255) / palette_gmask;
int b = (((ix >> palette_bshift) & palette_bmask) * 255) / palette_bmask;
return b | (g << 8) | (r << 16) | unchecked((int)0xFF000000);
case PaletteMode.PALETTE_RANDOM:
return randomColorHash(x);
case PaletteMode.PALETTE_GREY:
long lx = (x >= 0) ? x : (x + (1L << 32));
int grey = (int)((lx * 255L) / palette_greymax);
Expand All @@ -1097,25 +1142,10 @@ Color getPalette(long x)
return Color.FromArgb(p);
}

void randomPalette()
{
// randomizes the entire palette, not just the current used area,
// and does not switch to custom palette mode.
for (int i = 0; i < PALETTE_SIZE; ++i)
{
setPalette(i,
random.Next() & 255,
random.Next() & 255,
random.Next() & 255);
}
palette_path = "";
}

void autoPalette() // regenerate automatic palettes
{
autoPaletteSetup();
if (palette_mode == PaletteMode.PALETTE_CUSTOM) return;
if (palette_mode == PaletteMode.PALETTE_RANDOM) { randomPalette(); return; }
if (preset.bpp > PALETTE_BITS) return;
palette_path = "";
for (int i=0; i < (1 << preset.bpp); ++i)
Expand Down Expand Up @@ -1794,9 +1824,8 @@ void presetMenu_Select(object sender, EventArgs e) // clicking on a generated pr
{
ToolStripMenuItem item = (ToolStripMenuItem)sender;
int index = (int)item.Tag;
int old_bpp = preset.bpp;
preset = presets[index].copy();
if (old_bpp != preset.bpp && palette_mode != PaletteMode.PALETTE_RANDOM) autoPalette();
autoPalette();
scrollRange();
redrawPalette();
redrawPreset();
Expand Down Expand Up @@ -2047,9 +2076,8 @@ private void checkChunky_CheckedChanged(object sender, EventArgs e)

private void numericBPP_ValueChanged(object sender, EventArgs e)
{
int old_bpp = preset.bpp;
preset.bpp = (int)numericBPP.Value;
if (old_bpp != preset.bpp && palette_mode != PaletteMode.PALETTE_RANDOM) autoPalette();
autoPalette();
redrawPalette();
redrawPreset();
redrawPixels();
Expand Down Expand Up @@ -2174,9 +2202,8 @@ private void buttonLoadPreset_Click(object sender, EventArgs e)
Preset p = new Preset();
if (p.loadFile(d.FileName))
{
int old_bpp = preset.bpp;
preset = p;
if (old_bpp != preset.bpp && palette_mode != PaletteMode.PALETTE_RANDOM) autoPalette();
autoPalette();
scrollRange();
redrawPalette();
redrawPreset();
Expand Down Expand Up @@ -2340,19 +2367,16 @@ private void bgBox_Click(object sender, EventArgs e)

private void buttonAutoPal_Click(object sender, EventArgs e)
{
palette_mode = (PaletteMode)(comboBoxPalette.SelectedIndex + 1);
autoPalette();
redrawPalette();
redrawPixels();
randomColorSeed(); // reseed the random palette
comboBoxPalette_SelectedIndexChanged(sender, e);
}

private void comboBoxPalette_SelectedIndexChanged(object sender, EventArgs e)
{
// generate new palette if we were previously using an automatic palette
if (palette_mode != PaletteMode.PALETTE_CUSTOM)
{
buttonAutoPal_Click(sender, e);
}
palette_mode = (PaletteMode)(comboBoxPalette.SelectedIndex + 1);
autoPalette();
redrawPalette();
redrawPixels();
}

private void buttonLoadPal_Click(object sender, EventArgs e)
Expand Down Expand Up @@ -2689,6 +2713,7 @@ private void BinxelviewForm_Load(object sender, EventArgs e)
fixed_h = this.Height - (pixelScroll.Height + 0); // fixed height should cut off pixel view entirely
main_w = this.Width;
main_h = this.Height;
randomColorSeed();

// set default options
defaultOption();
Expand Down

0 comments on commit 9c2e80c

Please sign in to comment.