Mercurial > hg > forks > yadex
view src/palview.cc @ 117:0612954ba99c default tip
Cosmetics.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Mon, 06 Oct 2014 16:36:48 +0300 |
parents | f05330267c66 |
children |
line wrap: on
line source
/* * palview.cc * Palette (PLAYPAL & COLORMAP) viewer * AYM 1999-11-11 */ /* This file is part of Yadex. Yadex incorporates code from DEU 5.21 that was put in the public domain in 1994 by Raphaël Quinet and Brendon Wyber. The rest of Yadex is Copyright © 1997-2003 André Majorel and others. 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; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #include "yadex.h" #include <X11/Xlib.h> #include "colour.h" #include "gcolour2.h" #include "gfx.h" #include "palview.h" #include "rgb.h" #include "wadfile.h" #include "wads.h" #include "ytime.h" /* * Palette viewer::run * The only public method of the palette viewer. */ // One COLORMAP entry. Wrapped in struct to avoid array<->pointer problems typedef struct { uint8_t c[DOOM_COLOURS]; } colormap_entry_t; void Palette_viewer::run() { int lines = (ncolours + columns - 1) / columns; const int pwidth = columns * (pixels + 1); const int pheight = lines * (pixels + 1); int width = 2 * BOX_BORDER + 2 * WIDE_HSPACING + pwidth; int height = 2 * BOX_BORDER + 3 * WIDE_VSPACING + pheight + 7 * FONTH; int x0 = (cfg.ScrMaxX - width) / 2; int y0 = (cfg.ScrMaxY - height) / 2; int nmaps = 0; // Number of entries in the COLORMAP lump colormap_entry_t **colormap = 0; rgb_c *playpal = 0; // Load the PLAYPAL lump do { playpal = new rgb_c[DOOM_COLOURS]; for (size_t n = 0; n < DOOM_COLOURS; n++) playpal[n].set(0, 0, 0); const char *lump_name = "PLAYPAL"; MDirPtr dir = FindMasterDir(cfg.MasterDir, lump_name); if (dir == NULL) { warn("%s: lump not found\n", lump_name); break; } const Wad_file *wf = dir->wadfile; if (dir->dir.size % (3 * DOOM_COLOURS) != 0) { warn("%s has weird size (%ld, not mult of %d), ignoring tail\n", lump_name, (long) dir->dir.size, (int) (DOOM_COLOURS * 3)); } wf->seek(dir->dir.start); if (wf->error()) { warn("%s: seek error\n", lump_name); break; } playpal = new rgb_c[DOOM_COLOURS]; for (size_t n = 0; n < DOOM_COLOURS; n++) { char buf[3]; wf->read_bytes(buf, sizeof buf); playpal[n].set(buf[0], buf[1], buf[2]); } if (wf->error()) warn("%s: read error\n", lump_name); } while (0); // Load the COLORMAP lump do { const char *lump_name = "COLORMAP"; MDirPtr dir = FindMasterDir(cfg.MasterDir, lump_name); if (dir == NULL) { warn("%s: lump not found\n", lump_name); break; } const Wad_file *wf = dir->wadfile; nmaps = dir->dir.size / DOOM_COLOURS; if ((long) DOOM_COLOURS * nmaps != dir->dir.size) { warn("%s: has weird size (%ld, not mult of %d), ignoring tail\n", lump_name, (long) dir->dir.size, (int) DOOM_COLOURS); } if (nmaps > 200) { warn("%s has too many (%d) entries, keeping only 200 first\n", lump_name, nmaps); nmaps = 200; } wf->seek(dir->dir.start); if (wf->error()) { warn("%s: seek error\n", lump_name); break; } colormap = new colormap_entry_t *[nmaps]; for (int n = 0; n < nmaps; n++) { colormap[n] = new colormap_entry_t; wf->read_bytes(colormap[n]->c, sizeof colormap[n]->c); } if (wf->error()) warn("%s: read error\n", lump_name); } while (0); // On to the real business ix0 = x0 + BOX_BORDER + WIDE_HSPACING; iy0 = y0 + BOX_BORDER + WIDE_VSPACING; int tx0 = ix0; // Top left corner of text int ty0 = y0 + BOX_BORDER + 2 * WIDE_VSPACING + pheight; push_colour(0); // Save current colour #define DECIDX(i,n) do { i = (i - n + ncolours) % ncolours; } while (0) #define INCIDX(i,n) do { i = (i + n ) % ncolours; } while (0) int mapno = 0; bool mapping = true; int is_drawn = 0; const int YID_WINDOW = 0x01; const int YID_CURSOR = 0x02; const int YID_PALETTE = 0x04; const int YID_TEXT = 0x08; int cursor_phase = 0; int display_phase = 0; unsigned long cursor_time = 0; i = 0; ofs = 0; for (;;) { int mi = colormap[mapno]->c[i]; // Mapped index int ei = mapping ? mi : i; // Effective index int mapped_to = 0; // N. distinct colours that map to i for (int n = 0; n < ncolours; n++) for (int m = 0; m < nmaps; m++) if (colormap[m]->c[n] == i) { mapped_to++; break; // Don't count the same mapper twice } int maps_to = 0; // N. distinct colours that i maps to { bitvec_c mappee(ncolours); for (int m = 0; m < nmaps; m++) mappee.set(colormap[m]->c[i]); for (int n = 0; n < ncolours; n++) if (mappee.get(n)) maps_to++; } // Draw the window if (!(is_drawn & YID_WINDOW)) { DrawScreenBox3D(x0, y0, x0 + width - 1, y0 + height - 1); is_drawn = YID_WINDOW; // Redraw everything else } // Draw the cursor (frame around the current cell) { const int cycle = 800; // 800 ms unsigned long current_time = y_milliseconds(); unsigned long elapsed_time = current_time - cursor_time; cursor_time = current_time; #if 0 cursor_time += elapsed_time - elapsed_time % cycle; // Normalize elapsed_time = current_time - cursor_time; #endif cursor_phase = (cursor_phase + elapsed_time) % cycle; if ((cursor_phase >= cycle / 2) != (display_phase >= cycle / 2)) is_drawn &= ~YID_CURSOR; if (!(is_drawn & YID_CURSOR)) { draw_cursor(WINFG, cursor_phase >= cycle / 2); display_phase = cursor_phase; is_drawn |= YID_CURSOR; } } // Draw a (pixels x pixels) square for each colour if (!(is_drawn & YID_PALETTE)) { int x = 0; // Initialized only to prevent GCC from warning int y = 0; // Initialized only to prevent GCC from warning for (int n = 0; n < ncolours; n++) { if (n % columns == 0) { x = ix0; if (n == 0) y = iy0; else y += pixels + 1; } else x += pixels + 1; if (game_colour == 0) // If PLAYPAL not found set_pcolour(0); else { if (mapping) set_pcolour(game_colour [colormap[mapno]-> c[(n + ofs) % ncolours]]); else set_pcolour(game_colour[(n + ofs) % ncolours]); } DrawScreenBoxwh(x, y, pixels, pixels); } is_drawn |= YID_PALETTE; set_colour(WINFG_DIM); // Just to force the next set_colour() to do sth } // Draw the "caption" if (!(is_drawn & YID_TEXT)) { set_colour(WINBG); DrawScreenBoxwh(tx0, ty0, pwidth, 7 * FONTH); set_colour(WINFG); DrawScreenText(tx0, ty0, "Index %3d", i); push_colour(mapping ? WINFG : WINFG_DIM); DrawScreenText(tx0, -1, "Mapped index %3d", mi); pop_colour(); DrawScreenText(tx0, -1, "R %3d", playpal[ei].r); DrawScreenText(tx0, -1, "G %3d", playpal[ei].g); DrawScreenText(tx0, -1, "B %3d", playpal[ei].b); DrawScreenText(tx0, -1, "Mapped to by %3d", mapped_to); DrawScreenText(tx0, -1, "Maps to %3d", maps_to); push_colour(mapping ? WINFG : WINFG_DIM); DrawScreenText(tx0 + 18 * FONTW, ty0, "Colormap %3d", mapno); pop_colour(); is_drawn |= YID_TEXT; } // Process any events get_input_status(); if (is.key == YK_PU) // [Pgup] previous colormap { mapno--; if (mapno < 0) mapno = nmaps - 1; is_drawn &= ~(YID_PALETTE | YID_TEXT); } else if (is.key == YK_PD) // [Pgdn] next colormap { mapno++; if (mapno >= nmaps) mapno = 0; is_drawn &= ~(YID_PALETTE | YID_TEXT); } else if (is.key == YK_LEFT) // [Left] previous palette entry { draw_cursor(WINBG, false); DECIDX(i, 1); is_drawn &= ~(YID_PALETTE | YID_TEXT | YID_CURSOR); cursor_phase = 0; } else if (is.key == YK_RIGHT) // [Right] next palette entry { draw_cursor(WINBG, false); INCIDX(i, 1); is_drawn &= ~(YID_TEXT | YID_CURSOR); cursor_phase = 0; } else if (is.key == YK_UP) // [Up] previous palette row { draw_cursor(WINBG, false); DECIDX(i, columns); is_drawn &= ~(YID_TEXT | YID_CURSOR); cursor_phase = 0; } else if (is.key == YK_DOWN) // [Down] next palette row { draw_cursor(WINBG, false); INCIDX(i, columns); is_drawn &= ~(YID_TEXT | YID_CURSOR); cursor_phase = 0; } else if (is.key == YK_END // [End], [$]: end of current line || is.key == '$') { draw_cursor(WINBG, false); i += columns - i % columns - 1; is_drawn &= ~(YID_TEXT | YID_CURSOR); cursor_phase = 0; } else if (is.key == YK_HOME // [Home], [0], [^]: start of cur. line || is.key == '^' || is.key == '0') { draw_cursor(WINBG, false); i -= i % columns; is_drawn &= ~(YID_TEXT | YID_CURSOR); cursor_phase = 0; } else if (is.key == YK_RETURN) // [Return]: beginning of next line { draw_cursor(WINBG, false); i += columns - i % columns; is_drawn &= ~(YID_TEXT | YID_CURSOR); cursor_phase = 0; } #if 0 // Conflicts with "rotate" else if (is.key == '-') // [-]: beginning of previous line { draw_cursor(WINBG, false); i -= columns + i % columns; is_drawn &= ~(YID_TEXT | YID_CURSOR); cursor_phase = 0; } #endif else if (is.key == 'G' // [G], [L]: beginning of last line || is.key == 'L') { draw_cursor(WINBG, false); i = (lines - 1) * columns; is_drawn &= ~(YID_TEXT | YID_CURSOR); cursor_phase = 0; } else if (is.key == 'H') // [H] beginning of first line { draw_cursor(WINBG, false); i = 0; is_drawn &= ~(YID_TEXT | YID_CURSOR); cursor_phase = 0; } else if (is.key == 'm') // [m] toggle mapping { mapping = !mapping; is_drawn &= ~(YID_PALETTE | YID_TEXT); } else if (is.key == 'M') // [M] beginning of middle line { draw_cursor(WINBG, false); i = (lines / 2) * columns; is_drawn &= ~(YID_TEXT | YID_CURSOR); cursor_phase = 0; } else if (is.key == '+' || is.key == '=') // [+] increment offset { INCIDX(ofs, 1); INCIDX(i, 1); is_drawn &= ~(YID_PALETTE | YID_TEXT); } else if (is.key == '-') // [-] decrement offset { DECIDX(ofs, 1); DECIDX(i, 1); is_drawn &= ~(YID_PALETTE | YID_TEXT); } else if (is.key == YK_ESC) // [Esc] quit { break; } else if (is.key == YE_EXPOSE) { is_drawn = 0; // Redraw everything } else; } pop_colour(); // Restore current colour delete[]playpal; for (int n = 0; n < nmaps; n++) delete colormap[n]; delete[]colormap; } void Palette_viewer::draw_cursor(int c, bool phase) { const int a = (i + ncolours - ofs) % ncolours; const int side = pixels + 2; const int x0 = ix0 - 1 + (side - 1) * (a % columns); const int y0 = iy0 - 1 + (side - 1) * (a / columns); const int x1 = x0 + side - 1; const int y1 = y0 + side - 1; if (c == WINBG) { set_colour(c); DrawScreenRect(x0, y0, side, side); } else { const int l1 = side / 2; const int l2 = side - l1; // FIXME this cursor looks ugly set_colour(phase ? BLACK : WHITE); DrawScreenLineLen(x0, y0, l1, 0); DrawScreenLineLen(x0, y0, 0, l1); DrawScreenLineLen(x1, y1, 0, -l1); DrawScreenLineLen(x1, y1, -l1, 0); set_colour(phase ? WHITE : BLACK); DrawScreenLineLen(x1, y0, -l2, 0); DrawScreenLineLen(x1, y0, 0, l2); DrawScreenLineLen(x0, y1, 0, -l2); DrawScreenLineLen(x0, y1, l2, 0); } }