diff --git a/graphics/text/.gitignore b/graphics/text/.gitignore index b93d8485..4d76487d 100644 --- a/graphics/text/.gitignore +++ b/graphics/text/.gitignore @@ -3,6 +3,10 @@ wi*.gif wilv*.gif cwilv*.gif dmwilv*.gif -help*.gif +helpbg.png +help.gif +helpoverlay.png +helptext.png +helpttl.gif prboom.gif graphics.stamp diff --git a/graphics/text/Makefile b/graphics/text/Makefile index c36fc27d..8e078db1 100644 --- a/graphics/text/Makefile +++ b/graphics/text/Makefile @@ -55,14 +55,79 @@ graphics.stamp: config.py fontchars ../../lumps/fraggle/freedoom.bex ./textgen @mv graphics.tmp $@ -help.gif: helpbg.gif helptext.gif helpttl.gif - convert helpbg.gif \ - -draw 'image over 0,0 0,0 helptext.gif' \ - -draw 'image over 140,5 0,0 helpttl.gif' \ +# Generate transparent image containing text for the HELP screen: +helptext.png: + python smtextgen helptext.png 320x200 \ + 10,25 "Weapons" \ + 10,67 "Ammo" \ + 110,67 "Shells" \ + 220,67 "Backpack" \ + 10,90 "Missiles" \ + 170,90 "Energy" \ + 10,115 "Health" \ + 170,115 "Armor" \ + 145,140 "Map" \ + 10,140 "Overdrive" \ + 10,163 "Night vis" \ + 10,182 "Invisibility" \ + 135,182 "Invuln" \ + 255,182 "Keys" \ + 130,163 "Hazard suit" + +# Build on helptext.png by adding the title and sprites: +helpoverlay.png : helptext.png helpttl.gif + convert helptext.png \ + -draw 'image over 150,5 0,0 "helpttl.gif"' \ + -draw 'image over 80,25 0,0 "../../sprites/shota0.gif"' \ + -draw 'image over 150,25 0,0 "../../sprites/sgn2a0.gif"' \ + -draw 'image over 210,20 0,0 "../../sprites/mguna0.gif"' \ + -draw 'image over 10,40 0,0 "../../sprites/launa0.gif"' \ + -draw 'image over 80,40 0,0 "../../sprites/plasa0.gif"' \ + -draw 'image over 150,40 0,0 "../../sprites/bfuga0.gif"' \ + -draw 'image over 240,40 0,0 "../../sprites/csawa0.gif"' \ + -draw 'image over 53,67 0,0 "../../sprites/clipa0.gif"' \ + -draw 'image over 68,62 0,0 "../../sprites/ammoa0.gif"' \ + -draw 'image over 160,67 0,0 "../../sprites/shela0.gif"' \ + -draw 'image over 180,62 0,0 "../../sprites/sboxa0.gif"' \ + -draw 'image over 76,78 0,0 "../../sprites/rocka0.gif"' \ + -draw 'image over 95,82 0,0 "../../sprites/broka0.gif"' \ + -draw 'image over 220,90 0,0 "../../sprites/cella0.gif"' \ + -draw 'image over 240,81 0,0 "../../sprites/celpa0.gif"' \ + -draw 'image over 290,55 0,0 "../../sprites/bpaka0.gif"' \ + -draw 'image over 63,113 0,0 "../../sprites/bon1a0.gif"' \ + -draw 'image over 78,112 0,0 "../../sprites/stima0.gif"' \ + -draw 'image over 96,107 0,0 "../../sprites/media0.gif"' \ + -draw 'image over 128,107 0,0 "../../sprites/pstra0.gif"' \ + -draw 'image over 220,113 0,0 "../../sprites/bon2a0.gif"' \ + -draw 'image over 240,105 0,0 "../../sprites/arm1b0.gif"' \ + -draw 'image over 280,105 0,0 "../../sprites/arm2b0.gif"' \ + -draw 'image over 175,130 0,0 "../../sprites/pmapa0.gif"' \ + -draw 'image over 84,132 0,0 "../../sprites/soula0.gif"' \ + -draw 'image over 110,132 0,0 "../../sprites/megaa0.gif"' \ + -draw 'image over 80,160 0,0 "../../sprites/pvisa0.gif"' \ + -draw 'image over 100,172 0,0 "../../sprites/pinsa0.gif"' \ + -draw 'image over 185,174 0,0 "../../sprites/pinva0.gif"' \ + -draw 'image over 246,142 0,0 "../../sprites/rkeya0.gif"' \ + -draw 'image over 261,142 0,0 "../../sprites/ykeya0.gif"' \ + -draw 'image over 276,142 0,0 "../../sprites/bkeya0.gif"' \ + -draw 'image over 246,162 0,0 "../../sprites/rskua0.gif"' \ + -draw 'image over 261,162 0,0 "../../sprites/yskua0.gif"' \ + -draw 'image over 276,162 0,0 "../../sprites/bskua0.gif"' \ + -draw 'image over 215,142 0,0 "../../sprites/suita0.gif"' \ + -transparent '#00ffff' \ + helpoverlay.png + +# Background for the help screen is a color shifted version of INTERPIC: +helpbg.png: ../interpic.gif + convert ../interpic.gif -fill '#5599ff' -tint 100 helpbg.png + +# Draw the overlay with text and sprites onto the background to get the +# HELP screen: +help.gif: helpbg.png helpoverlay.png + convert helpbg.png \ + -draw 'image over 0,0 0,0 helpoverlay.png' \ help.gif -helpbg.gif: ../interpic.gif - convert ../interpic.gif -fill '#0077ff' -tint 50 helpbg.gif - clean: - rm -f $(TEXTGEN_GRAPHICS) helpbg.gif help.gif graphics.stamp *.pyc + rm -f $(TEXTGEN_GRAPHICS) helpbg.png help.gif \ + helpoverlay.png helptext.png graphics.stamp *.pyc diff --git a/graphics/text/config.py b/graphics/text/config.py index fa6ac55e..fa39a5e2 100644 --- a/graphics/text/config.py +++ b/graphics/text/config.py @@ -107,6 +107,9 @@ blue_graphics = { } red_graphics = { + # Title for the HELP/HELP1 screen: + 'helpttl': 'Help', + 'm_ngame': 'New Game', 'm_option': 'Options', 'm_loadg': 'Load Game', @@ -216,12 +219,6 @@ red_graphics = { 'm_multi': 'Multiplayer', } -# Rendered with transparent background: -transparent_graphics = { - # Title for the HELP/HELP1 screen: - 'helpttl': 'Help', -} - def read_bex_lump(filename): """Read the BEX (Dehacked) lump from the given filename. diff --git a/graphics/text/helptext.gif b/graphics/text/helptext.gif deleted file mode 100644 index 3a64709a..00000000 Binary files a/graphics/text/helptext.gif and /dev/null differ diff --git a/graphics/text/smtextgen b/graphics/text/smtextgen new file mode 100755 index 00000000..f790d050 --- /dev/null +++ b/graphics/text/smtextgen @@ -0,0 +1,203 @@ +#!/usr/bin/env python +# +# Copyright (c) 2014 +# Contributors to the Freedoom project. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the freedoom project nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# ---------------------------------------------------------------------- +# +# Script to generate text graphics using the "small" (HUD) font. +# + +from glob import glob +import sys +import subprocess +import re + +# ImageMagick commands used by this script: +CONVERT_COMMAND = 'convert' +IDENTIFY_COMMAND = 'identify' + +# Background color for output files. +BACKGROUND_COLOR = '#00ffff' + +# Width of a space character in pixels. +SPACE_WIDTH = 4 + +# Height of the font. +FONT_HEIGHT = 7 + +# Regexp to match dimensions/x,y coordinate pair. +DIMENSION_MATCH_RE = re.compile(r'(\d+)[x,](\d+)') + +# Output from 'identify' looks like this: +# fontchars/font033.gif GIF 9x16 9x16+0+0 8-bit sRGB 32c 194B 0.000u 0:00.000 +IDENTIFY_OUTPUT_RE = re.compile(r'(\S+)\s(\S+)\s(\d+)x(\d+)\s') + +def get_image_dimensions(filename): + proc = subprocess.Popen([IDENTIFY_COMMAND, filename], + stdout=subprocess.PIPE) + proc.wait() + + line = proc.stdout.readline().decode('utf-8') + match = IDENTIFY_OUTPUT_RE.match(line) + assert match is not None + return (int(match.group(3)), int(match.group(4))) + +def invoke_command(command): + """Invoke a command, printing the command to stdout. + + Args: + command: Command and arguments as a list. + """ + for arg in command: + if arg.startswith('-'): + sys.stdout.write("\\\n ") + + if ' ' in arg or '#' in arg: + sys.stdout.write(repr(arg)) + else: + sys.stdout.write(arg) + + sys.stdout.write(' ') + + sys.stdout.write('\n') + return subprocess.call(command) + +class Font(object): + def __init__(self): + self.get_font_widths() + + def compile_kerning_table(self, kerning_table): + """Given a dictionary of kerning patterns, compile Regexps.""" + + result = {} + for pattern, adjust in kerning_table.items(): + result[re.compile(pattern)] = adjust + return result + + def get_font_widths(self): + charfiles = glob('../stcfn*.gif') + self.char_widths = {} + for c in range(128): + filename = self.char_filename(chr(c)) + if filename not in charfiles: + continue + w, _ = get_image_dimensions(filename) + self.char_widths[chr(c)] = w + + def __contains__(self, c): + return c in self.char_widths + + def char_width(self, c): + return self.char_widths[c] + + def char_filename(self, c): + return '../stcfn%03d.gif' % (ord(c)) + + def draw_commands_for_text(self, text, x, y): + text = text.upper() + result = [] + + x1, y1 = x, y + + for c in text: + if c == '\n': + y1 += FONT_HEIGHT + x1 = x + elif c == ' ': + x1 += SPACE_WIDTH + + if c not in self: + continue + + filename = self.char_filename(c) + result.extend([ + '-draw', + 'image over %i,%i 0,0 "%s"' % + (x1, y1, filename) + ]) + x1 += self.char_width(c) + + return result + + +def parse_command_line(args): + if len(args) < 4 or (len(args) % 2) != 0: + return None + + result = { + 'filename': args[0], + 'strings': [], + } + + m = DIMENSION_MATCH_RE.match(args[1]) + if not m: + return None + result['dimensions'] = (int(m.group(1)), int(m.group(2))) + + i = 2 + while i < len(args): + m = DIMENSION_MATCH_RE.match(args[i]) + if not m: + return None + + xy = (int(m.group(1)), int(m.group(2))) + + result['strings'].append((xy, args[i + 1])) + i += 2 + + return result + + +args = parse_command_line(sys.argv[1:]) + +if not args: + print "Usage: smtextgen [...text commands...]" + print "Where each text command looks like:" + print " [x,y] [text]" + sys.exit(0) + +smallfont = Font() + +command_line = [ + CONVERT_COMMAND, + '-size', '%ix%i' % args['dimensions'], + 'xc:none', +] + +for xy, string in args['strings']: + command_line.extend(smallfont.draw_commands_for_text( + string, xy[0], xy[1])) + +command_line.extend(( + '-background', BACKGROUND_COLOR, + '-flatten', args['filename'], +)) + +invoke_command(command_line) + diff --git a/graphics/text/textgen b/graphics/text/textgen index e0e34c54..17f4ce73 100755 --- a/graphics/text/textgen +++ b/graphics/text/textgen @@ -249,5 +249,4 @@ font = Font('fontchars', kerning_table=FONT_KERNING_RULES) generate_graphics(red_graphics, color=COLOR_RED) generate_graphics(blue_graphics, color=COLOR_BLUE) generate_graphics(white_graphics, color=COLOR_WHITE) -generate_graphics(transparent_graphics, color=COLOR_RED, bgcolor=None)