source: abuse/branches/lol/src/gamma.cpp @ 694

Last change on this file since 694 was 694, checked in by Sam Hocevar, 10 years ago

core: refactor Palette so that it uses Array<u8vec3> instead of uint8_t *.

File size: 5.4 KB
Line 
1/*
2 *  Abuse - dark 2D side-scrolling platform game
3 *  Copyright (c) 1995 Crack dot Com
4 *  Copyright (c) 2005-2011 Sam Hocevar <sam@hocevar.net>
5 *
6 *  This software was released into the Public Domain. As with most public
7 *  domain software, no warranty is made or implied by Crack dot Com, by
8 *  Jonathan Clark, or by Sam Hocevar.
9 */
10
11#if defined HAVE_CONFIG_H
12#   include "config.h"
13#endif
14
15#include <math.h>
16
17#include "common.h"
18
19#include "game.h"
20
21#include "jwindow.h"
22#include "lisp.h"
23#include "scroller.h"
24#include "id.h"
25#include "cache.h"
26#include "dprint.h"
27#include "loader2.h"
28
29extern int dev_ok;
30Palette *old_pal = NULL;
31
32class gray_picker : public spicker
33{
34public:
35    int sc;
36    virtual void draw_item(image *screen, int x, int y, int num, int active)
37    {
38        long x2 = x + item_width() - 1;
39        long y2 = y + item_height() - 1;
40        screen->Bar(ivec2(x, y), ivec2(x2, y2), 0);
41        screen->Bar(ivec2(x, y), ivec2(x2 - 3, y2), sc + num);
42        if(active)
43        {
44            screen->Rectangle(ivec2(x, y), ivec2(x2, y2), 255);
45        }
46    }
47    void set_pos(int x) { cur_sel = x; }
48    virtual int total() { return 32; }
49    virtual int item_width() { return 12; }
50    virtual int item_height() { return 20; }
51    virtual int activate_on_mouse_move() { return 0; }
52
53    gray_picker(int X, int Y, int ID, int start, int current, ifield *Next) : spicker(X, Y, ID, 1, 20, 0, 0, Next)
54    {
55        cur_sel = current;
56        sc = start;
57        reconfigure();
58        cur_sel=current;
59    }
60};
61
62static char const *lang_string(char const *symbol)
63{
64    LSymbol *v = LSymbol::Find(symbol);
65    if (!v || !DEFINEDP(v->GetValue()))
66        return "Language symbol missing!";
67    return lstring_value(v->GetValue());
68}
69
70void gamma_correct(Palette *&pal, int force_menu)
71{
72    long dg=0,old_dg=0;
73    int abort=0;
74
75    // see if user has already done this routine
76    LSymbol *gs = LSymbol::Find("darkest_gray");
77
78    if(old_pal)
79    {
80        delete pal;
81        pal = old_pal;
82        old_pal = nullptr;
83    }
84
85    if(gs && DEFINEDP(gs->GetValue()) && !force_menu)
86    {
87        dg = lnumber_value(gs->GetValue());
88    }
89    else
90    {
91        if(gs && DEFINEDP(gs->GetValue()))
92        {
93            dg = old_dg = lnumber_value(gs->GetValue());
94        }
95        // load in a fine gray palette they can chose from
96        Palette *gray_pal = pal->Copy();
97        int tc = 32;
98
99        for(int i = 0; i < tc; i++)
100            gray_pal->SetColor(i, u8vec3(i * 4));
101
102        gray_pal->load();
103
104        int wm_bc = wm->bright_color(), wm_mc = wm->medium_color(), wm_dc = wm->dark_color();
105
106        u8vec3 br = (u8vec3)min((ivec3)pal->GetColor(wm_bc), ivec3(255 - 20)) + u8vec3(20);
107        u8vec3 md = (u8vec3)max((ivec3)pal->GetColor(wm_mc), ivec3(20)) - u8vec3(20);
108        u8vec3 dr = (u8vec3)max((ivec3)pal->GetColor(wm_dc), ivec3(40)) - u8vec3(40);
109
110        wm->set_colors(gray_pal->FindClosest(br),
111                       gray_pal->FindClosest(md),
112                       gray_pal->FindClosest(dr));
113
114        int sh = wm->font()->Size().y + 35;
115        button *but = new button(5, 5 + sh * 3, ID_GAMMA_OK, cache.img(ok_button),
116            new info_field(35, 10 + sh * 3, ID_NULL, lang_string("gamma_msg"), 0));
117
118        gray_picker *gp = new gray_picker(2, 5 + sh, ID_GREEN_PICKER, 0, dg / 4, but);
119        gp->set_pos(dg / 4);
120
121        Jwindow *gw = wm->CreateWindow(ivec2(xres / 2 - 190,
122                                             yres / 2 - 90), ivec2(-1), gp);
123
124        Event ev;
125        wm->flush_screen();
126        do
127        {
128            do
129            {
130                wm->get_event(ev);
131            } while(ev.type == EV_MOUSE_MOVE && wm->IsPending());
132            wm->flush_screen();
133            if(ev.type == EV_CLOSE_WINDOW)
134                abort = 1;
135            if(ev.type == EV_KEY && ev.key == JK_ESC)
136                abort = 1;
137        } while(!abort && (ev.type != EV_MESSAGE || ev.message.id != ID_GAMMA_OK));
138
139        dg = ((spicker *)gw->inm->get(ID_GREEN_PICKER))->first_selected() * 4;
140
141        wm->close_window(gw);
142        wm->flush_screen();
143
144        wm->set_colors(wm_bc, wm_mc, wm_dc);
145        delete gray_pal;
146
147        if(!abort)
148        {
149            char *gammapath;
150            FILE *fp;
151
152            gammapath = (char *)malloc(strlen(get_save_filename_prefix()) + 10);
153            sprintf(gammapath, "%sgamma.lsp", get_save_filename_prefix());
154            fp = open_FILE(gammapath, "wb");
155            if(fp)
156            {
157                fprintf(fp, "(setq darkest_gray %ld)\n", dg);
158                fclose(fp);
159                LSpace *sp = LSpace::Current;
160                LSpace::Current = &LSpace::Perm;
161                LSymbol::FindOrCreate("darkest_gray")->SetNumber(dg);
162
163                LSpace::Current = sp;
164            }
165            else
166            {
167                dprintf("Unable to write to file gamma.lsp\n");
168            }
169            free(gammapath);
170        }
171    }
172
173    if(abort)
174        dg = old_dg;
175
176    if(dg < 1)
177        dg = 1;
178    else if(dg > 128)
179        dg = 128;
180
181    double gamma = log(dg / 255.0) / log(16.0 / 255.0);
182
183    old_pal = pal;
184    pal = new Palette;
185    for(int i = 0; i < 256; i++)
186    {
187        u8vec3 old = old_pal->GetColor(i);
188        pal->SetColor(i, u8vec3(lol::pow(old.r / 255.0, gamma) * 255,
189                                lol::pow(old.g / 255.0, gamma) * 255,
190                                lol::pow(old.b / 255.0, gamma) * 255));
191    }
192
193    pal->load();
194}
Note: See TracBrowser for help on using the repository browser.