source: abuse/trunk/src/gamma.cpp @ 528

Last change on this file since 528 was 512, checked in by Sam Hocevar, 11 years ago

imlib: use vec2i for image::size and unroll all necessary changes
everywhere else in the code.

File size: 5.7 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 or
8 *  Jonathan Clark.
9 */
10
11#include "config.h"
12
13#include <math.h>
14
15#include "common.h"
16
17#include "game.h"
18
19#include "jwindow.h"
20#include "lisp.h"
21#include "scroller.h"
22#include "id.h"
23#include "cache.h"
24#include "dprint.h"
25#include "loader2.h"
26
27extern int dev_ok;
28palette *old_pal = NULL;
29
30class gray_picker : public spicker
31{
32public:
33    int sc;
34    virtual void draw_item(image *screen, int x, int y, int num, int active)
35    {
36        long x2 = x + item_width() - 1;
37        long y2 = y + item_height() - 1;
38        screen->bar(x, y, x2, y2, 0);
39        screen->bar(x, y, x2 - 3, y2, sc + num);
40        if(active)
41        {
42            screen->rectangle(x, y, x2, y2, 255);
43        }
44    }
45    void set_pos(int x) { cur_sel = x; }
46    virtual int total() { return 32; }
47    virtual int item_width() { return 12; }
48    virtual int item_height() { return 20; }
49    virtual int activate_on_mouse_move() { return 0; }
50
51    gray_picker(int X, int Y, int ID, int start, int current, ifield *Next) : spicker(X, Y, ID, 1, 20, 0, 0, Next)
52    {
53        cur_sel = current;
54        sc = start;
55        reconfigure();
56        cur_sel=current;
57    }
58};
59
60static char const *lang_string(char const *symbol)
61{
62    LSymbol *v = LSymbol::Find(symbol);
63    if (!v || !DEFINEDP(v->GetValue()))
64        return "Language symbol missing!";
65    return lstring_value(v->GetValue());
66}
67
68void gamma_correct(palette *&pal, int force_menu)
69{
70    long dg=0,old_dg=0;
71    int abort=0;
72
73    // see if user has already done this routine
74    LSymbol *gs = LSymbol::Find("darkest_gray");
75
76    if(old_pal)
77    {
78        delete pal;
79        pal = old_pal;
80        old_pal = NULL;
81    }
82
83    if(gs && DEFINEDP(gs->GetValue()) && !force_menu)
84    {
85        dg = lnumber_value(gs->GetValue());
86    }
87    else
88    {
89        if(gs && DEFINEDP(gs->GetValue()))
90        {
91            dg = old_dg = lnumber_value(gs->GetValue());
92        }
93        // load in a fine gray palette they can chose from
94        palette *gray_pal = pal->copy();
95        int i = 0;
96        int tc = 32;
97
98        for(; i < tc; i++)
99        {
100            gray_pal->set(i, i * 4, i * 4, i * 4);
101        }
102
103        gray_pal->load();
104
105        int wm_bc = wm->bright_color(), wm_mc = wm->medium_color(), wm_dc = wm->dark_color();
106
107        int br_r = pal->red(wm_bc) + 20;
108        if(br_r > 255)
109            br_r = 255;
110        int br_g = pal->green(wm_bc) + 20;
111        if(br_g > 255)
112            br_g = 255;
113        int br_b = pal->blue(wm_bc) + 20;
114        if(br_b > 255)
115            br_b = 255;
116
117        int md_r = pal->red(wm_mc) - 20;
118        if(md_r < 0)
119            md_r = 0;
120        int md_g = pal->green(wm_mc) - 20;
121        if(md_g < 0)
122            md_g = 0;
123        int md_b = pal->blue(wm_mc) - 20;
124        if(md_b < 0)
125            md_b = 0;
126
127        int dr_r = pal->red(wm_dc) - 40;
128        if(dr_r < 0)
129            dr_r = 0;
130        int dr_g = pal->green(wm_dc) - 40;
131        if(dr_g < 0)
132            dr_g = 0;
133        int dr_b = pal->blue(wm_dc) - 40;
134        if(dr_b < 0)
135            dr_b = 0;
136
137        wm->set_colors(gray_pal->find_closest(br_r, br_g, br_b),
138            gray_pal->find_closest(md_r, md_g, md_b),
139            gray_pal->find_closest(dr_r, dr_g, dr_b));
140
141        int sh = wm->font()->height() + 35;
142        button *but = new button(5, 5 + sh * 3, ID_GAMMA_OK, cache.img(ok_button),
143            new info_field(35, 10 + sh * 3, ID_NULL, lang_string("gamma_msg"), 0));
144
145        gray_picker *gp = new gray_picker(2, 5 + sh, ID_GREEN_PICKER, 0, dg / 4, but);
146        gp->set_pos(dg / 4);
147
148        Jwindow *gw = wm->new_window(xres / 2 - 190, yres / 2 - 90, -1, -1, gp);
149
150        event ev;
151        wm->flush_screen();
152        do
153        {
154            do
155            {
156                wm->get_event(ev);
157            } while(ev.type == EV_MOUSE_MOVE && wm->event_waiting());
158            wm->flush_screen();
159            if(ev.type == EV_CLOSE_WINDOW)
160                abort = 1;
161            if(ev.type == EV_KEY && ev.key == JK_ESC)
162                abort = 1;
163        } while(!abort && (ev.type != EV_MESSAGE || ev.message.id != ID_GAMMA_OK));
164
165        dg = ((spicker *)gw->inm->get(ID_GREEN_PICKER))->first_selected() * 4;
166
167        wm->close_window(gw);
168        wm->flush_screen();
169
170        wm->set_colors(wm_bc, wm_mc, wm_dc);
171        delete gray_pal;
172
173        if(!abort)
174        {
175            char *gammapath;
176            FILE *fp;
177
178            gammapath = (char *)malloc(strlen(get_save_filename_prefix()) + 10);
179            sprintf(gammapath, "%sgamma.lsp", get_save_filename_prefix());
180            fp = open_FILE(gammapath, "wb");
181            if(fp)
182            {
183                fprintf(fp, "(setq darkest_gray %ld)\n", dg);
184                fclose(fp);
185                int sp = current_space;
186                current_space = PERM_SPACE;
187                LSymbol::FindOrCreate("darkest_gray")->SetNumber(dg);
188
189                current_space = sp;
190            }
191            else
192            {
193                dprintf("Unable to write to file gamma.lsp\n");
194            }
195            free(gammapath);
196        }
197    }
198
199    if(abort)
200        dg = old_dg;
201
202    if(dg < 1)
203        dg = 1;
204    else if(dg > 128)
205        dg = 128;
206
207    double gamma = log(dg / 255.0) / log(16.0 / 255.0);
208
209    old_pal = pal;
210    pal = new palette;
211    for(int i = 0; i < 256; i++)
212    {
213        uint8_t oldr, oldg, oldb;
214        old_pal->get(i, oldr, oldg, oldb);
215        pal->set(i, (int)(pow(oldr / 255.0, gamma) * 255),
216            (int)(pow(oldg / 255.0, gamma) * 255),
217            (int)(pow(oldb / 255.0, gamma) * 255));
218    }
219
220    pal->load();
221}
Note: See TracBrowser for help on using the repository browser.