From c3c465f742846b524010cb72d07f4bbcced02cf4 Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Thu, 8 Nov 2018 21:56:06 +0100 Subject: [PATCH] customizable colors for game objects --- classes.h | 1 + config.cpp | 152 ++++++++++++++++++++++++++++++++++++++++++++++++---- control.cpp | 11 ---- dialogs.cpp | 22 ++++---- graph.cpp | 121 ++++++++++++++++++++++++++--------------- help.cpp | 4 +- hyper.h | 3 ++ init.cpp | 1 + 8 files changed, 240 insertions(+), 75 deletions(-) diff --git a/classes.h b/classes.h index f6938814..a5ce2aa0 100644 --- a/classes.h +++ b/classes.h @@ -239,6 +239,7 @@ extern monstertype minf[motypes]; extern itemtype iinf[ittypes]; extern const landtype linf[landtypes]; +extern color_t floorcolors[landtypes]; enum cpatterntype { cpFootball, cpThree, cpChess, cpSingle, cpSingleSym, cpOddEven, cpLarge, cpZebra, cpUnknown diff --git a/config.cpp b/config.cpp index 995f89d2..8ce1395f 100644 --- a/config.cpp +++ b/config.cpp @@ -17,6 +17,8 @@ videopar vid; #define ANDROID_SETTINGS ; #endif +extern color_t floorcolors[landtypes]; + charstyle& getcs(int id) { if(multi::players>1 && id >= 0 && id < multi::players) return multi::scs[id]; @@ -114,6 +116,11 @@ void loadcs(FILE *f, charstyle& cs, int xvernum) { } #endif +void savecolortable(colortable& ct, string name) { + for(int i=0; i= 32 && uni < 64) || uni == 'L') xuni = uni; + if((uni >= 32 && uni < 64) || uni == 'L' || uni == 'C') xuni = uni; if(xuni == 'u') vid.particles = !vid.particles; if(xuni == 'd') vid.graphglyph = (1+vid.graphglyph)%3; + + if(xuni == 'c') pushScreen(show_color_dialog); if(xuni == 'j') { dialog::editNumber(whatever, -10, 10, 1, 0, XLAT("whatever"), @@ -805,7 +829,7 @@ void showGraphConfig() { dialog::reaction = [] () { resetGeometry(); }; } - if(xuni == 'c') { + if(xuni == 'C') { dialog::editNumber(vid.mobilecompasssize, 0, 100, 10, 20, XLAT("compass size"), ""); // we need to check the moves dialog::reaction = checkmove; @@ -826,11 +850,6 @@ void showGraphConfig() { if(xuni =='p') vid.backeffects = !vid.backeffects; - if(xuni =='z') - dialog::editNumber(vid.aurastr, 0, 256, 10, 128, XLAT("aura brightness"), ""); - else if(xuni =='x') - dialog::editNumber(vid.aurasmoothen, 1, 180, 1, 5, XLAT("aura smoothening factor"), ""); - handleAllConfig(sym, xuni); }; } @@ -1391,6 +1410,117 @@ void showCustomizeChar() { }; } +void refresh_canvas() { + manual_celllister cl; + cl.add(cwt.at); + + int at = 0; + while(at < isize(cl.lst)) { + cell *c2 = cl.lst[at]; + c2->landparam = patterns::generateCanvas(c2); + at++; + + forCellEx(c3, c2) cl.add(c3); + } + } + +void edit_color_table(colortable& ct, const reaction_t& r = reaction_t()) { + cmode = sm::SIDE; + gamescreen(0); + dialog::init(XLAT("Customize colors and aura")); + + for(int i=0; iland == laMinefield) { + dialog::addItem(XLAT("minefield colors"), 'm'); + dialog::add_action([] () { pushScreen([] () { edit_color_table(minecolors); });}); + } + + if(viewdists) { + dialog::addItem(XLAT("distance colors"), 'd'); + dialog::add_action([] () { pushScreen([] () { edit_color_table(distcolors); });}); + } + + dialog::addInfo(XLAT("colors of some game objects can be edited by clicking them.")); + + dialog::addBreak(50); + + dialog::addSelItem(XLAT("aura brightness"), its(vid.aurastr), 'a'); + dialog::add_action([] () { dialog::editNumber(vid.aurastr, 0, 256, 10, 128, XLAT("aura brightness"), ""); }); + + dialog::addSelItem(XLAT("aura smoothening factor"), its(vid.aurasmoothen), 's'); + dialog::add_action([] () { dialog::editNumber(vid.aurasmoothen, 1, 180, 1, 5, XLAT("aura smoothening factor"), ""); }); + + dialog::addBreak(50); + dialog::addBack(); + dialog::display(); + + getcstat = '-'; + + keyhandler = [] (int sym, int uni) { + if(uni == '-') { + cell *c = mouseover; + if(!c) return; + else if(c == cwt.at) { + pushScreen(showCustomizeChar); + return; + } + else if(c->monst) + dialog::openColorDialog(minf[c->monst].color); + else if(c->item) + dialog::openColorDialog(iinf[c->item].color); + else if(c->wall) + dialog::openColorDialog(winf[c->wall].color); + else + dialog::openColorDialog(floorcolors[c->land]); + dialog::colorAlpha = false; + dialog::dialogflags |= sm::SIDE; + return; + } + else dialog::handleNavigation(sym, uni); + if(doexiton(sym, uni)) popScreen(); + }; + } + #if CAP_CONFIG void resetConfigMenu() { dialog::init(XLAT("reset all configuration")); diff --git a/control.cpp b/control.cpp index e8fdef54..d2d4812f 100644 --- a/control.cpp +++ b/control.cpp @@ -346,17 +346,6 @@ void handleKeyNormal(int sym, int uni) { if(uni == sym && DEFAULTNOR(sym)) { gmodekeys(sym, uni); - if(sym == '8') { - backcolor = backcolor ^ 0xFFFFFF; - bordcolor = bordcolor ^ 0xFFFFFF; - forecolor = forecolor ^ 0xFFFFFF; - printf("back = %x\n", backcolor); - } - if(sym == '9') { - pmodel = eModel(8 - pmodel); - // vid.yshift = 1 - vid.yshift; - // vid.drawmousecircle = true; - } if(sym == 'm' && canmove && (centerover == cwt ? mouseover : centerover.at)) performMarkCommand(mouseover); } diff --git a/dialogs.cpp b/dialogs.cpp index 502a0411..2a4be83c 100644 --- a/dialogs.cpp +++ b/dialogs.cpp @@ -472,27 +472,27 @@ namespace dialog { bool handleKeyColor(int sym, int uni) { unsigned& color = *colorPointer; + int shift = colorAlpha ? 0 : 8; if(uni >= 'A' && uni <= 'D') { int x = (mousex - (dcenter-dwidth/4)) * 510 / dwidth; if(x < 0) x = 0; if(x > 255) x = 255; - unsigned char* pts = (unsigned char*) &color; - pts[uni - 'A'] = x; + part(color, uni - 'A') = x; } else if(uni == ' ' || uni == '\n' || uni == '\r') { bool inHistory = false; - for(int i=0; i<10; i++) if(colorhistory[i] == (unsigned) color) + for(int i=0; i<10; i++) if(colorhistory[i] == (color << shift)) inHistory = true; - if(!inHistory) { colorhistory[lch] = color; lch++; lch %= 10; } + if(!inHistory) { colorhistory[lch] = (color << shift); lch++; lch %= 10; } if(reaction) reaction(); popScreen(); } else if(uni >= '0' && uni <= '9') { - color = colorhistory[uni - '0']; + color = colorhistory[uni - '0'] >> shift; } else if(palette && uni >= 'a' && uni < 'a'+(int) palette[0]) { - color = palette[1 + uni - 'a']; + color = palette[1 + uni - 'a'] >> shift; } else if(sym == SDLK_DOWN || sym == SDLK_KP2) { colorp = (colorp-1) & 3; @@ -514,6 +514,8 @@ namespace dialog { return false; } + bool colorAlpha; + void drawColorDialog() { cmode = sm::NUMBER | dialogflags; if(cmode & sm::SIDE) gamescreen(0); @@ -555,19 +557,20 @@ namespace dialog { for(int i=0; i<4; i++) { int y = vid.yres / 2 + (2-i) * vid.fsize * 2; + if(i == 3 && !colorAlpha) continue; color_t col = ((i==colorp) && !mousing) ? 0xFFD500 : dialogcolor; displayColorButton(dcenter - dwidth/4, y, "(", 0, 16, 0, col); - string rgt = ") "; rgt += "ABGR" [i]; + string rgt = ") "; rgt += "ABGR" [i+(colorAlpha?0:1)]; displayColorButton(dcenter + dwidth/4, y, rgt, 0, 0, 0, col); - displayColorButton(dcenter - dwidth/4 + dwidth * ((color >> (8*i)) & 0xFF) / 510, y, "#", 0, 8, 0, col); + displayColorButton(dcenter - dwidth/4 + dwidth * part(color, i) / 510, y, "#", 0, 8, 0, col); if(mousey >= y - vid.fsize && mousey < y + vid.fsize) getcstat = 'A' + i, inslider = true; } - displayColorButton(dcenter, vid.yres/2+vid.fsize * 6, XLAT("select this color") + " : " + itsh(color), ' ', 8, 0, color >> ash); + displayColorButton(dcenter, vid.yres/2+vid.fsize * 6, XLAT("select this color") + " : " + itsh(color), ' ', 8, 0, color >> (colorAlpha ? ash : 0)); if(extra_options) extra_options(); @@ -576,6 +579,7 @@ namespace dialog { void openColorDialog(unsigned int& col, unsigned int *pal) { colorPointer = &col; palette = pal; + colorAlpha = true; dialogflags = 0; pushScreen(drawColorDialog); reaction = reaction_t(); diff --git a/graph.cpp b/graph.cpp index 3447b7d4..ba3a0882 100644 --- a/graph.cpp +++ b/graph.cpp @@ -2691,6 +2691,53 @@ ld wavefun(ld x) { colortable nestcolors = { 0x800000, 0x008000, 0x000080, 0x404040, 0x700070, 0x007070, 0x707000, 0x606060 }; +color_t floorcolors[landtypes]; + +void init_floorcolors() { + for(int i=0; iwall].color; @@ -2735,29 +2782,33 @@ void setcolors(cell *c, color_t& wcol, color_t& fcol) { case laCrossroads2: case laCrossroads3: case laCrossroads4: case laCrossroads5: case laRose: case laPower: case laWildWest: case laHalloween: case laRedRock: case laDragon: case laStorms: case laTerracotta: case laMercuryRiver: - fcol = linf[c->land].color; break; + case laDesert: case laKraken: case laDocks: case laCA: + case laMotion: case laGraveyard: case laWineyard: case laLivefjord: + case laRlyeh: case laHell: case laCrossroads: case laJungle: + case laAlchemist: + fcol = floorcolors[c->land]; break; case laRuins: fcol = pseudohept(c) ? 0xC0E0C0 : 0x40A040; break; case laDual: - fcol = linf[c->land].color; + fcol = floorcolors[c->land]; if(c->landparam == 2) fcol = 0x40FF00; if(c->landparam == 3) fcol = 0xC0FF00; break; - case laDesert: fcol = 0xEDC9AF; break; - case laKraken: fcol = 0x20A020; break; - case laDocks: fcol = 0x202020; break; - case laCA: fcol = 0x404040; break; - case laMotion: fcol = 0xF0F000; break; - case laGraveyard: fcol = 0x107010; break; - case laWineyard: fcol = 0x006000; break; - case laLivefjord: fcol = 0x306030; break; - - case laBrownian: - fcol = wcol = gradient(0x002000, 0xFFFFFF, 0, c->landparam, 20); +#if CAP_COMPLEX2 + case laBrownian: { + using brownian::level; + fcol = wcol = + c->landparam == 0 ? 0x0000F0 : + c->landparam < level ? gradient(0x002000, 0xFFFFFF, 1, c->landparam, level-1) : + c->landparam < 2 * level ? 0xFFFF80 : + // gradient(0xFFFF80, 0xFFFF00, 2*level, c->landparam, 2*level-1) : + c->landparam < 3 * level ? 0xFF8000 : + // gradient(0xFF8000, 0xFFF000, 2*level, c->landparam, 3*level-1) : + 0xC00000; break; case laVolcano: { @@ -2781,25 +2832,20 @@ void setcolors(cell *c, color_t& wcol, color_t& fcol) { } case laMinefield: - fcol = 0x80A080; + fcol = floorcolors[c->land]; if(c->wall == waMineMine && ((cmode & sm::MAP) || !canmove)) fcol = wcol = 0xFF4040; break; case laCaribbean: if(c->wall != waCIsland && c->wall != waCIsland2) - fcol = 0x006000; + fcol = floorcolors[c->land]; break; - case laAlchemist: - fcol = 0x202020; - break; case laReptile: fcol = reptilecolor(c); break; - case laCrossroads: - fcol = (stereo::in_anaglyph() ? 0xFF3030 : 0xFF0000); - break; + case laCaves: case laEmerald: case laDeadCaves: fcol = 0x202020; if(c->land == laEmerald) @@ -2808,11 +2854,9 @@ void setcolors(cell *c, color_t& wcol, color_t& fcol) { if(c->wall == waCavewall) wcol = 0xC0FFC0; } break; - case laJungle: - fcol = (stereo::in_anaglyph() ? 0x408040 : 0x008000); - break; case laMirror: case laMirrorWall: case laMirrorOld: - fcol = 0x808080; + if(c->land == laMirrorWall) fcol = floorcolors[laMirror]; + else fcol = floorcolors[c->land]; break; case laDryForest: fcol = gradient(0x008000, 0x800000, 0, c->landparam, 10); @@ -2823,17 +2867,11 @@ void setcolors(cell *c, color_t& wcol, color_t& fcol) { else fcol = 0; if(c->wall == waPlatform) wcol = 0xF0F0A0; break; - case laRlyeh: - fcol = (stereo::in_anaglyph() ? 0x4080C0 : 0x004080); - break; - case laHell: - fcol = (stereo::in_anaglyph() ? 0xC03030 : 0xC00000); - break; case laCanvas: fcol = c->landparam; break; case laPalace: - fcol = 0x806020; + fcol = floorcolors[c->land]; if(c->wall == waClosedGate || c->wall == waOpenGate) fcol = wcol; break; @@ -2841,7 +2879,7 @@ void setcolors(cell *c, color_t& wcol, color_t& fcol) { fcol = (linf[c->barleft].color>>1) + (linf[c->barright].color>>1); break; case laZebra: - fcol = 0xE0E0E0; + fcol = floorcolors[c->land]; if(c->wall == waTrapdoor) fcol = 0x808080; break; case laHive: @@ -2861,7 +2899,7 @@ void setcolors(cell *c, color_t& wcol, color_t& fcol) { else if(c->wall == waSmallTree) wcol = 0x905000; break; case laOvergrown: case laClearing: - fcol = (c->land == laOvergrown/* || (celldistAlt(c)&1)*/) ? 0x00C020 : 0x60E080; + fcol = floorcolors[c->land]; if(c->wall == waSmallTree) wcol = 0x008060; else if(c->wall == waBigTree) wcol = 0x0080C0; break; @@ -2888,9 +2926,7 @@ void setcolors(cell *c, color_t& wcol, color_t& fcol) { break; case laHunting: - // fcol = pseudohept(c) ? 0x205050 : 0x306060; - fcol = 0x40E0D0; - fcol /= 2; + fcol = floorcolors[c->land]; if(pseudohept(c)) fcol = fcol * 3/4; break; @@ -2955,7 +2991,7 @@ void setcolors(cell *c, color_t& wcol, color_t& fcol) { else #endif if(d < 0) { - fcol = 0xA0A0A0; + fcol = floorcolors[c->land]; } else { // a nice floor pattern @@ -2975,11 +3011,12 @@ void setcolors(cell *c, color_t& wcol, color_t& fcol) { case laIce: case laCocytus: case laBlizzard: if(isIcyWall(c)) { float h = HEAT(c); - bool showcoc = c->land == laCocytus && chaosmode && !wmescher; + eLand l = c->land; + if(l == laCocytus && (!chaosmode || !wmescher)) l = laIce; - color_t colorN04 = showcoc ? 0x4080FF : 0x4040FF; + color_t colorN04 = l == laCocytus ? 0x4080FF : 0x4040FF; color_t colorN10 = 0x0000FF; - color_t color0 = c->land == laBlizzard ? 0x5050C0 : showcoc ? 0x80C0FF : 0x8080FF; + color_t color0 = floorcolors[c->land]; color_t color02 = 0xFFFFFF; color_t color06 = 0xFF0000; color_t color08 = 0xFFFF00; @@ -3035,7 +3072,7 @@ void setcolors(cell *c, color_t& wcol, color_t& fcol) { for(int i=0; itype; i++) if(c->move(i) && c->move(i)->item) itcolor = 1; if(c->item) itcolor |= 2; - fcol = 0x609F60 + 0x202020 * itcolor; + fcol = floorcolors[laHaunted] + 0x202020 * itcolor; forCellEx(c2, c) if(c2->monst == moFriendlyGhost) fcol = gradient(fcol, fghostcolor(c2), 0, .25, 1); diff --git a/help.cpp b/help.cpp index b53a49a8..e48d97c2 100644 --- a/help.cpp +++ b/help.cpp @@ -17,8 +17,8 @@ vector extra_keys = { "5 = change wall display mode", "6 = change grid", "7 = change heptagon marking", - "8 = change background color", - "9 = hyperboloid model", +// "8 = change background color", +// "9 = hyperboloid model", "qweasdzxc, hjklyubn, numpad = move/skip turn", "arrows = panning", "o = world overview", diff --git a/hyper.h b/hyper.h index 41ac8a0c..617074c5 100644 --- a/hyper.h +++ b/hyper.h @@ -1763,6 +1763,7 @@ namespace dialog { void addBigItem(string body, int key); void addColorItem(string body, int value, int key); void openColorDialog(color_t& col, color_t *pal = palette); + extern bool colorAlpha; void addHelp(string body); void addInfo(string body, color_t color = dialogcolor); void addItem(string body, int key); @@ -4329,5 +4330,7 @@ bool haveaura(); string parser_help(); static const ld degree = M_PI / 180; + +void show_color_dialog(); } diff --git a/init.cpp b/init.cpp index 70ffe061..7a441d91 100644 --- a/init.cpp +++ b/init.cpp @@ -23,6 +23,7 @@ int startseed = 0; eLand firstland0; void initAll() { + init_floorcolors(); showstartmenu = true; ca::init(); #if CAP_COMMANDLINE