Rename Qt4 directory to Qt
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
Install.Qt NHSUBST
|
||||
qpe-nethack.control NH_header=no
|
||||
knethack.lnk NH_header=no
|
||||
* NH_filestag=(file%s_for_the_Qt_3_widget_library_-_X11,_Windows,_Mac_OS_X,_or_Qtopia)
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleGetInfoHTML</key>
|
||||
<string>http://www.nethack.org</string>
|
||||
<key>CFBundleGetInfoString</key>
|
||||
<string>Copyright (C) 1985-2003 Stichting Mathematisch Centrum</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>nethack.icns</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.nethack.qt</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>3.5.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>NHak</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,113 @@
|
||||
Installing NetHack with a Qt or KDE interface
|
||||
---------------------------------------------
|
||||
$NHDT-Date: 1524689332 2018/04/25 20:48:52 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.11 $
|
||||
# Copyright (c) 2004 by Warwick Allison
|
||||
# NetHack may be freely redistributed. See license for details.
|
||||
|
||||
This document describes the installation of NetHack with a Qt interface
|
||||
on UNIX/X11 or Mac OS X. This code should also work with Qt/Windows, but
|
||||
support for that is not currently official.
|
||||
|
||||
You can download Qt from http://www.trolltech.com.
|
||||
You need Qt 2.0 or later to use this code.
|
||||
|
||||
To use this code on UNIX (not Mac OS X):
|
||||
|
||||
1. follow the directions for the UNIX installation (in ../../sys/unix)
|
||||
to create the Makefiles.
|
||||
|
||||
2. ../../include/config.h
|
||||
|
||||
define QT_GRAPHICS (search for it). You can comment out
|
||||
TTY_GRAPHICS if you want to, or leave it in to support both
|
||||
interfaces (in which case be sure you have the right curses
|
||||
libraries etc. required for that interface).
|
||||
|
||||
3. ../../src/Makefile
|
||||
|
||||
ensure your QTDIR environment variable was set correctly when
|
||||
you installed Qt - $QTDIR/include/qwidget.h should exist, for
|
||||
example.
|
||||
|
||||
ensure CXX and LINK are set to the compiler and linker you need
|
||||
for compiling and linking C++ software (e.g., set both to g++).
|
||||
|
||||
add $(WINQTSRC), $(WINQTOBJ), and $(WINQTLIB) to WINSRC, WINOBJ,
|
||||
and WINLIB respectively, and compile. This will give you an
|
||||
executable supporting both Qt and tty windowing.
|
||||
|
||||
4. ../../Makefile (the top-level makefile)
|
||||
|
||||
Just change the VARDATND setting to contain the files
|
||||
"x11tiles", "rip.xpm", and "nhsplash.xpm":
|
||||
|
||||
VARDATND = x11tiles rip.xpm nhsplash.xpm
|
||||
|
||||
5. Follow all the instructions in ../../sys/unix/Install.unx for
|
||||
the remainder of the installation process.
|
||||
|
||||
6. Consider adding the lines below to your .nethackrc, as they are
|
||||
likely to give the best interface for this window port:
|
||||
|
||||
OPTIONS=name:player,number_pad,menustyle:partial,!time,showexp
|
||||
OPTIONS=hilite_pet,toptenwin,msghistory:200,windowtype:Qt
|
||||
|
||||
If you are using KDE, you may want to also try the KDE version. It just
|
||||
uses the KDE menubar and follows other KDE conventions - there is no
|
||||
extra functionality. To do so:
|
||||
|
||||
1. Ensure that you have KDE 2.x libraries on your system
|
||||
(in 1999 KDE 1.x was the norm)
|
||||
|
||||
2. ../../src/Makefile
|
||||
|
||||
Add $(KDECXXFLAGS) to the CXXFLAGS definition, $(KDELFLAGS) to
|
||||
the LFLAGS definition and $(WINKDELIB) to WINLIB.
|
||||
|
||||
3. Some additional files here - knh-mini.xpm, knh.xpm, and
|
||||
knethack.lnk are useful if you want to install "knethack" in
|
||||
the KDE games directory.
|
||||
|
||||
If you are using Qtopia, you can compile NetHack for that environment
|
||||
with the following additional steps:
|
||||
|
||||
1. First be sure that you can build a simple Qtopia application,
|
||||
such as the examples that ship with Qtopia. Do not attempt
|
||||
something as challenging to compile as NetHack before you can
|
||||
already build a Qtopia application for your target device.
|
||||
|
||||
2. If you are cross-compiling (eg. targetting an ARM-based handheld),
|
||||
be sure to follow the steps for cross-compiling in the Makefile.src
|
||||
and Makefile.utl files.
|
||||
|
||||
3. To CXXFLAGS in Makefile.src, add:
|
||||
-DQWS -I$(QPEDIR)/include -fno-rtti -fno-exceptions
|
||||
|
||||
4. Rather than -lqt in WINQTLIB, have:
|
||||
-L$(QPEDIR)/lib -lqpe -lqte
|
||||
|
||||
5. After building, use the "mkipks" program that ships with Qtopia
|
||||
to package the result into an ipk file.
|
||||
|
||||
To use this code on Mac OS X:
|
||||
|
||||
1. follow the directions for the UNIX installation (in ../../sys/unix)
|
||||
to create the Makefiles.
|
||||
|
||||
2. quite a number of changes are required to the Makefiles. They are
|
||||
slowly being made 'official', but for now they are all in the patch
|
||||
nethack-macosx-qt.patch:
|
||||
|
||||
cd ../..
|
||||
patch -p0 < win/Qt/nethack-macosx-qt.patch
|
||||
|
||||
3. Follow all the instructions in ../../sys/unix/Install.unx for
|
||||
the remainder of the installation process (basically run "make install").
|
||||
|
||||
4. Consider adding the lines below to a file called "NetHack Defaults",
|
||||
in your "Library/Preferences" folder, as they are likely to give
|
||||
the best interface for this window port:
|
||||
|
||||
OPTIONS=name:player,number_pad,menustyle:partial,!time,showexp
|
||||
OPTIONS=hilite_pet,toptenwin,msghistory:200,windowtype:Qt
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
# KDE Config File
|
||||
# Call this file knethack.kdelnk or knethack.desktop
|
||||
[KDE Desktop Entry]
|
||||
Name=Nethack
|
||||
Name[fr]=Nethack
|
||||
Name[hu]=Nethack
|
||||
Name[no]=Nethack
|
||||
Name[sk]=Nethack
|
||||
Name[cs]=Nethack
|
||||
Name[hr]=Nethack
|
||||
Name[pt]=Nethack
|
||||
Name[pt_BR]=Nethack
|
||||
Icon=knh.xpm
|
||||
Exec=knethack -caption "%c" %i %m
|
||||
Type=Application
|
||||
DocPath=knethack/index.html
|
||||
Comment=The classic Unix role-playing game - fight monsters and seek the Amulet of Yendor for your god!
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/* XPM */
|
||||
static char *noname[] = {
|
||||
/* width height ncolors chars_per_pixel */
|
||||
"16 16 7 1",
|
||||
/* colors */
|
||||
" c #000000",
|
||||
". c #DCDCDC",
|
||||
"X c #008080",
|
||||
"o c #A0A0A0",
|
||||
"O c None",
|
||||
"+ c #FFFFFF",
|
||||
"@ c #C3C3C3",
|
||||
/* pixels */
|
||||
"OOOOOOOOOOOOOOOO",
|
||||
"OOO+O+++@@@O@OOO",
|
||||
"O+O+++++@@@@@O.O",
|
||||
"O+o+XXXXX X @ . ",
|
||||
"O+o+XXXX X X@ . ",
|
||||
"OO +XXXXX X @ O ",
|
||||
"OOO+XXXX X X@ OO",
|
||||
"OOO+XXXXX X @ OO",
|
||||
"OOO+XXXX X X@ OO",
|
||||
"OOOO+XXXX X@ OO",
|
||||
"OOOO+XXX X . OO",
|
||||
"OOO+O+XXX . . OO",
|
||||
"OO+++ +X . ... O",
|
||||
"O+++. O+. .... ",
|
||||
"OO+. OOOOOO.. O",
|
||||
"OOOOOOOOOOOOOOOO"
|
||||
};
|
||||
@@ -0,0 +1,67 @@
|
||||
/* XPM */
|
||||
static char *noname[] = {
|
||||
/* width height ncolors chars_per_pixel */
|
||||
"40 40 20 1",
|
||||
/* colors */
|
||||
" c #000000",
|
||||
". c #0000C0",
|
||||
"X c #FFC0FF",
|
||||
"o c #FFC0C0",
|
||||
"O c #DCDCDC",
|
||||
"+ c #C0C0FF",
|
||||
"@ c #008080",
|
||||
"# c #A0A0A0",
|
||||
"$ c None",
|
||||
"% c #000080",
|
||||
"& c #585858",
|
||||
"* c #800080",
|
||||
"= c #FFFFFF",
|
||||
"- c #FFFFC0",
|
||||
"; c #00C0C0",
|
||||
": c #C0FFFF",
|
||||
"> c #C0FFC0",
|
||||
", c #C3C3C3",
|
||||
"< c #FFDCA8",
|
||||
"1 c #0000FF",
|
||||
/* pixels */
|
||||
"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
|
||||
"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
|
||||
"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
|
||||
"$$$$$$$$=$$$$$$=,==<,=<,$$$$$$,$$$$$$$$$",
|
||||
"$$$$$$$$==$$$=====,=<>,<><$$$<>$$$$$$$$$",
|
||||
"$$$$$$$$===$====,==>,=<,<,,$,,<$$$$$$$$$",
|
||||
"$$$==$$$==========<=<,><,><<><,$$$,<$$$$",
|
||||
"$$$====$========,==,,=<>,<,>,<,$<><,$$$$",
|
||||
"$$$====$==========<=<,,<<><,<><$,,<>$$$$",
|
||||
"$$$$#&&&==$#$#$#@#$&@#&&@&&&&,, && $$",
|
||||
"$$$;#@&@==;#;#;#$;&#@&@$&@&@$>< &@ $$",
|
||||
"$$$====&==###1##.##@&#&@&&$&&<, <>O< $$",
|
||||
"$$$====&==$;##;##;&#@&@$&@&@&>, O<,> $$",
|
||||
"$$$==&@&==#1#;##.##@&#&@&$@$&,< ,< $$",
|
||||
"$$$$ ==###1#;##.#@$&&&@&&@-, $ $$",
|
||||
"$$$$$ =X;#;###&;#&@#&@$&@$&,< $$ $$$",
|
||||
"$$$$$$ ==#$+@+1##@#&@&$@&&&@<> $$$$$$",
|
||||
"$$$$$$$$=X;#1#$#@##@&#@&&&@$&<, $$$$$$",
|
||||
"$$$$$$$$==##;#;##1$#@&$@$&&@&>< $$$$$$",
|
||||
"$$$$$$$$=X;###1#@##@&#@&&@$&&O, $$$$$$",
|
||||
"$$$$$$$$==#1#;##;#.#@&&$@&@&@<> $$$$$$",
|
||||
"$$$$$$$$$==###;#*;#&@#&@&&$&O< $$$$$$$",
|
||||
"$$$$$$$$$==;#1,$;#&#@$@&$@&@<, $$$$$$$",
|
||||
"$$$$$$$$$$=X####.##@&#&&@&&<O $$$$$$$$",
|
||||
"$$$$$$$$$$==;#;##;*#@&@$&&@O< $$$$$$$",
|
||||
"$$$$$$$$==$==1##.#;&@+&&@&O< <, $$$$$$",
|
||||
"$$$$$$$===#:=#;###&+%&@$&O> ><, $$$$$$",
|
||||
"$$$$$$====@&=O##@#;&@#&&,< <,>< $$$$$",
|
||||
"$$$$$===#$== ==$1#&#&@&O> ,<$#,,> $$$$",
|
||||
"$$$$===#;#== ==$#;&@#O, >,#;&<,< $$$$",
|
||||
"$$$==$#;*@O< ====Oo,> <,&$#@&O, $$$",
|
||||
"$$$==;$#&&<, $===<,< <O@&;#&>< $$",
|
||||
"$$$==##;&O>, $$==,> $$ ,<&&#$@o, $$",
|
||||
"$$$===X=O,< $$$$$$$$$$$$$>OO,Oo> $$$",
|
||||
"$$$$====,< $$$$$$$$$$$$$$,<,>,<, $$$$",
|
||||
"$$$$$===<> $$$$$$$$$$$$$$$$><,<> $$$$",
|
||||
"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
|
||||
"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
|
||||
"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
|
||||
"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$"
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
Files: bin/nethack pics/NetHack.png apps/Games/nethack.desktop games/lib/nethackdir/[a-r]* games/lib/nethackdir/[t-z]* games/lib/nethackdir/save games/lib/nethackdir/s*.* games/lib/nethackdir/[A-Z0-9]*
|
||||
Priority: optional
|
||||
Section: qpe/games
|
||||
Maintainer: Warwick Allison <warwick@trolltech.com>
|
||||
Architecture: arm
|
||||
Version: 3.5.0-1
|
||||
Depends: qpe-base ($QPE_VERSION)
|
||||
Description: NetHack - The Dungeon Game
|
||||
Graphical version of NetHack for Qtopia
|
||||
@@ -0,0 +1,168 @@
|
||||
/* NetHack 3.6 qt_clust.cpp $NHDT-Date: 1524684507 2018/04/25 19:28:27 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.8 $ */
|
||||
/* Copyright (c) Warwick Allison, 1999. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
#include "qt_clust.h"
|
||||
|
||||
static
|
||||
void include(QRect& r, const QRect& rect)
|
||||
{
|
||||
if (rect.left()<r.left()) {
|
||||
r.setLeft(rect.left());
|
||||
}
|
||||
if (rect.right()>r.right()) {
|
||||
r.setRight(rect.right());
|
||||
}
|
||||
if (rect.top()<r.top()) {
|
||||
r.setTop(rect.top());
|
||||
}
|
||||
if (rect.bottom()>r.bottom()) {
|
||||
r.setBottom(rect.bottom());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
A Clusterizer groups rectangles (QRects) into non-overlapping rectangles
|
||||
by a merging heuristic.
|
||||
*/
|
||||
Clusterizer::Clusterizer(int maxclusters) :
|
||||
cluster(new QRect[maxclusters]),
|
||||
count(0),
|
||||
max(maxclusters)
|
||||
{ }
|
||||
|
||||
Clusterizer::~Clusterizer()
|
||||
{
|
||||
delete [] cluster;
|
||||
}
|
||||
|
||||
void Clusterizer::clear()
|
||||
{
|
||||
count=0;
|
||||
}
|
||||
|
||||
void Clusterizer::add(int x, int y)
|
||||
{
|
||||
add(QRect(x,y,1,1));
|
||||
}
|
||||
|
||||
void Clusterizer::add(int x, int y, int w, int h)
|
||||
{
|
||||
add(QRect(x,y,w,h));
|
||||
}
|
||||
|
||||
void Clusterizer::add(const QRect& rect)
|
||||
{
|
||||
QRect biggerrect(rect.x()-1,rect.y()-1,rect.width()+2,rect.height()+2);
|
||||
|
||||
//assert(rect.width()>0 && rect.height()>0);
|
||||
|
||||
int cursor;
|
||||
|
||||
for (cursor=0; cursor<count; cursor++) {
|
||||
if (cluster[cursor].contains(rect)) {
|
||||
// Wholly contained already.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int lowestcost=9999999;
|
||||
int cheapest=-1;
|
||||
for (cursor=0; cursor<count; cursor++) {
|
||||
if (cluster[cursor].intersects(biggerrect)) {
|
||||
QRect larger=cluster[cursor];
|
||||
include(larger,rect);
|
||||
int cost=larger.width()*larger.height()
|
||||
- cluster[cursor].width()*cluster[cursor].height();
|
||||
|
||||
if (cost < lowestcost) {
|
||||
bool bad=FALSE;
|
||||
for (int c=0; c<count && !bad; c++) {
|
||||
bad=cluster[c].intersects(larger) && c!=cursor;
|
||||
}
|
||||
if (!bad) {
|
||||
cheapest=cursor;
|
||||
lowestcost=cost;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cheapest>=0) {
|
||||
include(cluster[cheapest],rect);
|
||||
return;
|
||||
}
|
||||
|
||||
if (count < max) {
|
||||
cluster[count++]=rect;
|
||||
return;
|
||||
}
|
||||
|
||||
// Do cheapest of:
|
||||
// add to closest cluster
|
||||
// do cheapest cluster merge, add to new cluster
|
||||
|
||||
lowestcost=9999999;
|
||||
cheapest=-1;
|
||||
for (cursor=0; cursor<count; cursor++) {
|
||||
QRect larger=cluster[cursor];
|
||||
include(larger,rect);
|
||||
int cost=larger.width()*larger.height()
|
||||
- cluster[cursor].width()*cluster[cursor].height();
|
||||
if (cost < lowestcost) {
|
||||
bool bad=FALSE;
|
||||
for (int c=0; c<count && !bad; c++) {
|
||||
bad=cluster[c].intersects(larger) && c!=cursor;
|
||||
}
|
||||
if (!bad) {
|
||||
cheapest=cursor;
|
||||
lowestcost=cost;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// XXX could make an heuristic guess as to whether we
|
||||
// XXX need to bother looking for a cheap merge.
|
||||
|
||||
int cheapestmerge1=-1;
|
||||
int cheapestmerge2=-1;
|
||||
|
||||
for (int merge1=0; merge1<count; merge1++) {
|
||||
for (int merge2=0; merge2<count; merge2++) {
|
||||
if (merge1!=merge2) {
|
||||
QRect larger=cluster[merge1];
|
||||
include(larger,cluster[merge2]);
|
||||
int cost=larger.width()*larger.height()
|
||||
- cluster[merge1].width()*cluster[merge1].height()
|
||||
- cluster[merge2].width()*cluster[merge2].height();
|
||||
if (cost < lowestcost) {
|
||||
bool bad=FALSE;
|
||||
for (int c=0; c<count && !bad; c++) {
|
||||
bad=cluster[c].intersects(larger) && c!=cursor;
|
||||
}
|
||||
if (!bad) {
|
||||
cheapestmerge1=merge1;
|
||||
cheapestmerge2=merge2;
|
||||
lowestcost=cost;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cheapestmerge1>=0) {
|
||||
include(cluster[cheapestmerge1],cluster[cheapestmerge2]);
|
||||
cluster[cheapestmerge2]=cluster[count--];
|
||||
} else {
|
||||
// if (!cheapest) debugRectangles(rect);
|
||||
include(cluster[cheapest],rect);
|
||||
}
|
||||
|
||||
// NB: clusters do not intersect (or intersection will
|
||||
// overwrite). This is a result of the above algorithm,
|
||||
// given the assumption that (x,y) are ordered topleft
|
||||
// to bottomright.
|
||||
}
|
||||
|
||||
const QRect& Clusterizer::operator[](int i)
|
||||
{
|
||||
return cluster[i];
|
||||
}
|
||||
+5312
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,413 @@
|
||||
/* NetHack 3.6 tileedit.cpp $NHDT-Date: 1524684508 2018/04/25 19:28:28 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.10 $ */
|
||||
/* Copyright (c) Warwick Allison, 1999. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
/*
|
||||
Build this little utility program if you want to use it to edit the tile
|
||||
files. Move tileedit.cpp and tileedit.h to ../../util, add the
|
||||
3 lines below to the Makefile there and "make tileedit".
|
||||
|
||||
tileedit: tileedit.cpp $(TEXT_IO)
|
||||
moc -o tileedit.moc tileedit.h
|
||||
$(CC) -o tileedit -I../include -I$(QTDIR)/include -L$(QTDIR)/lib tileedit.cpp $(TEXT_IO) -lqt
|
||||
*/
|
||||
|
||||
|
||||
#include "tileedit.h"
|
||||
#include <qapplication.h>
|
||||
#include <qmainwindow.h>
|
||||
#include <qkeycode.h>
|
||||
#include <qpopupmenu.h>
|
||||
#include <qmenubar.h>
|
||||
#include <qpainter.h>
|
||||
#include <qstatusbar.h>
|
||||
#include <qhbox.h>
|
||||
#include <qlabel.h>
|
||||
|
||||
extern "C" {
|
||||
#include "config.h"
|
||||
#include "tile.h"
|
||||
extern const char *FDECL(tilename, (int, int));
|
||||
}
|
||||
|
||||
#define TILES_ACROSS 20
|
||||
|
||||
TilePickerTab::TilePickerTab(const char* basename, int i, QWidget* parent) :
|
||||
QWidget(parent)
|
||||
{
|
||||
id = i;
|
||||
filename = basename;
|
||||
filename += ".txt";
|
||||
num = 0;
|
||||
int index = 0;
|
||||
for (int real=0; real<2; real++) {
|
||||
if ( real ) {
|
||||
image.create( TILES_ACROSS*TILE_X,
|
||||
((num+TILES_ACROSS-1)/TILES_ACROSS)*TILE_Y, 32 );
|
||||
}
|
||||
if ( !fopen_text_file(filename.latin1(), RDTMODE) ) {
|
||||
// XXX handle better
|
||||
exit(1);
|
||||
}
|
||||
pixel p[TILE_Y][TILE_X];
|
||||
while ( read_text_tile(p) ) {
|
||||
if ( real ) {
|
||||
int ox = (index%TILES_ACROSS)*TILE_X;
|
||||
int oy = (index/TILES_ACROSS)*TILE_Y;
|
||||
for ( int y=0; y<TILE_Y; y++ ) {
|
||||
QRgb* rgb = ((QRgb*)image.scanLine(oy+y)) + ox;
|
||||
for ( int x=0; x<TILE_X; x++ ) {
|
||||
*rgb++ = qRgb(p[y][x].r, p[y][x].g, p[y][x].b);
|
||||
}
|
||||
}
|
||||
index++;
|
||||
} else {
|
||||
// Just count...
|
||||
num++;
|
||||
}
|
||||
}
|
||||
fclose_text_file();
|
||||
}
|
||||
image = image.convertDepth( 8, AvoidDither );
|
||||
pixmap.convertFromImage( image );
|
||||
}
|
||||
|
||||
bool TilePickerTab::save()
|
||||
{
|
||||
if ( !fopen_text_file(filename.latin1(), WRTMODE) ) {
|
||||
// XXX handle better
|
||||
exit(1);
|
||||
}
|
||||
pixel p[TILE_Y][TILE_X];
|
||||
for ( int index=0; index < num; index++ ) {
|
||||
int ox = (index%TILES_ACROSS)*TILE_X;
|
||||
int oy = (index/TILES_ACROSS)*TILE_Y;
|
||||
for ( int y=0; y<TILE_Y; y++ ) {
|
||||
uchar* c = image.scanLine(oy+y) + ox;
|
||||
for ( int x=0; x<TILE_X; x++ ) {
|
||||
QRgb rgb = image.color(*c++);
|
||||
p[y][x].r = qRed(rgb);
|
||||
p[y][x].g = qGreen(rgb);
|
||||
p[y][x].b = qBlue(rgb);
|
||||
}
|
||||
}
|
||||
write_text_tile(p);
|
||||
}
|
||||
fclose_text_file();
|
||||
}
|
||||
|
||||
void TilePickerTab::mousePressEvent(QMouseEvent* e)
|
||||
{
|
||||
int ox = e->x()-e->x()%TILE_X;
|
||||
int oy = e->y()-e->y()%TILE_Y;
|
||||
QImage subimage = image.copy(ox,oy,TILE_X,TILE_Y);
|
||||
if ( e->button() == RightButton ) {
|
||||
setCurrent(subimage);
|
||||
} else {
|
||||
last_pick = ox/TILE_X + oy/TILE_Y*TILES_ACROSS;
|
||||
}
|
||||
emit pick(subimage);
|
||||
emit pickName(tilename(id, last_pick));
|
||||
}
|
||||
|
||||
void TilePickerTab::setCurrent(const QImage& i)
|
||||
{
|
||||
int ox = last_pick%TILES_ACROSS * TILE_X;
|
||||
int oy = last_pick/TILES_ACROSS * TILE_Y;
|
||||
bitBlt( &image, ox, oy, &i );
|
||||
bitBlt( &pixmap, ox, oy, &i );
|
||||
repaint( ox, oy, TILE_X, TILE_Y, FALSE );
|
||||
}
|
||||
|
||||
QSize TilePickerTab::sizeHint() const
|
||||
{
|
||||
return pixmap.size();
|
||||
}
|
||||
|
||||
void TilePickerTab::paintEvent( QPaintEvent* )
|
||||
{
|
||||
QPainter p(this);
|
||||
p.drawPixmap(0,0,pixmap);
|
||||
}
|
||||
|
||||
static struct {
|
||||
const char* name;
|
||||
TilePickerTab* tab;
|
||||
} tileset[] = {
|
||||
{ "monsters", 0 },
|
||||
{ "objects", 0 },
|
||||
{ "other", 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
TilePicker::TilePicker(QWidget* parent) :
|
||||
QTabWidget(parent)
|
||||
{
|
||||
for (int i=0; tileset[i].name; i++) {
|
||||
QString tabname = tileset[i].name;
|
||||
tabname[0] = tabname[0].upper();
|
||||
tileset[i].tab = new TilePickerTab(tileset[i].name,i+1,this);
|
||||
addTab( tileset[i].tab, tabname );
|
||||
connect( tileset[i].tab, SIGNAL(pick(const QImage&)),
|
||||
this, SIGNAL(pick(const QImage&)) );
|
||||
connect( tileset[i].tab, SIGNAL(pickName(const QString&)),
|
||||
this, SIGNAL(pickName(const QString&)) );
|
||||
}
|
||||
}
|
||||
|
||||
void TilePicker::setCurrent(const QImage& i)
|
||||
{
|
||||
((TilePickerTab*)currentPage())->setCurrent(i);
|
||||
}
|
||||
|
||||
void TilePicker::save()
|
||||
{
|
||||
for (int i=0; tileset[i].tab; i++) {
|
||||
tileset[i].tab->save();
|
||||
}
|
||||
}
|
||||
|
||||
TrivialTileEditor::TrivialTileEditor( QWidget* parent ) :
|
||||
QWidget(parent)
|
||||
{
|
||||
}
|
||||
|
||||
const QImage& TrivialTileEditor::image() const
|
||||
{
|
||||
return img;
|
||||
}
|
||||
|
||||
void TrivialTileEditor::setColor( QRgb rgb )
|
||||
{
|
||||
pen = rgb;
|
||||
for (penpixel = 0;
|
||||
penpixel<img.numColors()-1 && (img.color(penpixel)&0xffffff)!=(pen.rgb()&0xffffff);
|
||||
penpixel++)
|
||||
continue;
|
||||
}
|
||||
|
||||
void TrivialTileEditor::setImage( const QImage& i )
|
||||
{
|
||||
img = i;
|
||||
setColor(pen.rgb()); // update penpixel
|
||||
repaint(FALSE);
|
||||
}
|
||||
|
||||
void TrivialTileEditor::paintEvent( QPaintEvent* e )
|
||||
{
|
||||
QRect r = e->rect();
|
||||
QPoint tl = imagePoint(r.topLeft());
|
||||
QPoint br = imagePoint(r.bottomRight());
|
||||
r = QRect(tl,br).intersect(img.rect());
|
||||
QPainter painter(this);
|
||||
for (int y=r.top(); y<=r.bottom(); y++) {
|
||||
for (int x=r.left(); x<=r.right(); x++) {
|
||||
paintPoint(painter,QPoint(x,y));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TrivialTileEditor::paintPoint(QPainter& painter, QPoint p)
|
||||
{
|
||||
QPoint p1 = screenPoint(p);
|
||||
QPoint p2 = screenPoint(p+QPoint(1,1));
|
||||
QColor c = img.color(img.scanLine(p.y())[p.x()]);
|
||||
painter.fillRect(QRect(p1,p2-QPoint(1,1)), c);
|
||||
}
|
||||
|
||||
void TrivialTileEditor::mousePressEvent(QMouseEvent* e)
|
||||
{
|
||||
QPoint p = imagePoint(e->pos());
|
||||
if ( !img.rect().contains(p) )
|
||||
return;
|
||||
uchar& pixel = img.scanLine(p.y())[p.x()];
|
||||
if ( e->button() == LeftButton ) {
|
||||
pixel = penpixel;
|
||||
QPainter painter(this);
|
||||
paintPoint(painter,p);
|
||||
} else if ( e->button() == RightButton ) {
|
||||
emit pick( img.color(pixel) );
|
||||
} else if ( e->button() == MidButton ) {
|
||||
QPainter painter(this);
|
||||
if ( pixel != penpixel )
|
||||
fill(painter,p,pixel);
|
||||
}
|
||||
}
|
||||
|
||||
void TrivialTileEditor::fill(QPainter& painter, QPoint p, uchar from)
|
||||
{
|
||||
if ( img.rect().contains(p) ) {
|
||||
uchar& pixel = img.scanLine(p.y())[p.x()];
|
||||
if ( pixel == from ) {
|
||||
pixel = penpixel;
|
||||
paintPoint(painter,p);
|
||||
fill(painter, p+QPoint(-1,0), from);
|
||||
fill(painter, p+QPoint(+1,0), from);
|
||||
fill(painter, p+QPoint(0,-1), from);
|
||||
fill(painter, p+QPoint(0,+1), from);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TrivialTileEditor::mouseReleaseEvent(QMouseEvent* e)
|
||||
{
|
||||
emit edited(image());
|
||||
}
|
||||
|
||||
void TrivialTileEditor::mouseMoveEvent(QMouseEvent* e)
|
||||
{
|
||||
QPoint p = imagePoint(e->pos());
|
||||
if ( !img.rect().contains(p) )
|
||||
return;
|
||||
uchar& pixel = img.scanLine(p.y())[p.x()];
|
||||
pixel = penpixel;
|
||||
QPainter painter(this);
|
||||
paintPoint(painter,p);
|
||||
}
|
||||
|
||||
QPoint TrivialTileEditor::imagePoint(QPoint p) const
|
||||
{
|
||||
return QPoint(p.x()*TILE_X/width(), p.y()*TILE_Y/height());
|
||||
}
|
||||
|
||||
QPoint TrivialTileEditor::screenPoint(QPoint p) const
|
||||
{
|
||||
return QPoint(p.x()*width()/TILE_X, p.y()*height()/TILE_Y);
|
||||
}
|
||||
|
||||
QSizePolicy TrivialTileEditor::sizePolicy() const
|
||||
{
|
||||
return QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding, TRUE );
|
||||
}
|
||||
|
||||
QSize TrivialTileEditor::sizeHint() const
|
||||
{
|
||||
return sizeForWidth(-1);
|
||||
}
|
||||
|
||||
QSize TrivialTileEditor::sizeForWidth(int w) const
|
||||
{
|
||||
if ( w < 0 )
|
||||
return QSize(TILE_X*32,TILE_Y*32);
|
||||
else
|
||||
return QSize(w,w*TILE_Y/TILE_X);
|
||||
}
|
||||
|
||||
|
||||
TilePalette::TilePalette( QWidget* parent ) :
|
||||
QWidget(parent)
|
||||
{
|
||||
num = 0;
|
||||
rgb = 0;
|
||||
}
|
||||
|
||||
TilePalette::~TilePalette()
|
||||
{
|
||||
delete rgb;
|
||||
}
|
||||
|
||||
void TilePalette::setFromImage( const QImage& i )
|
||||
{
|
||||
num = i.numColors();
|
||||
rgb = new QRgb[num];
|
||||
memcpy(rgb, i.colorTable(), num*sizeof(QRgb));
|
||||
repaint(FALSE);
|
||||
}
|
||||
|
||||
void TilePalette::setColor(QRgb c)
|
||||
{
|
||||
for (int i=0; i<num; i++)
|
||||
if ( c == rgb[i] ) {
|
||||
emit pick(c);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
QSizePolicy TilePalette::sizePolicy() const
|
||||
{
|
||||
return QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum, FALSE );
|
||||
}
|
||||
|
||||
QSize TilePalette::sizeHint() const
|
||||
{
|
||||
return QSize(num*16,16);
|
||||
}
|
||||
|
||||
void TilePalette::paintEvent( QPaintEvent* )
|
||||
{
|
||||
QPainter p(this);
|
||||
for (int i=0; i<num; i++) {
|
||||
int x1 = width()*i/num;
|
||||
int x2 = width()*(i+1)/num;
|
||||
p.fillRect(x1,0,x2-x1,height(),QColor(rgb[i]));
|
||||
}
|
||||
}
|
||||
|
||||
void TilePalette::mousePressEvent(QMouseEvent* e)
|
||||
{
|
||||
int c = e->x()*num/width();
|
||||
emit pick(rgb[c]);
|
||||
}
|
||||
|
||||
TileEditor::TileEditor(QWidget* parent) :
|
||||
QVBox(parent),
|
||||
editor(this),
|
||||
palette(this)
|
||||
{
|
||||
connect( &palette, SIGNAL(pick(QRgb)),
|
||||
&editor, SLOT(setColor(QRgb)) );
|
||||
connect( &editor, SIGNAL(pick(QRgb)),
|
||||
&palette, SLOT(setColor(QRgb)) );
|
||||
connect( &editor, SIGNAL(edited(const QImage&)),
|
||||
this, SIGNAL(edited(const QImage&)) );
|
||||
}
|
||||
|
||||
void TileEditor::edit(const QImage& i)
|
||||
{
|
||||
editor.setImage(i);
|
||||
palette.setFromImage(i);
|
||||
}
|
||||
|
||||
const QImage& TileEditor::image() const
|
||||
{
|
||||
return editor.image();
|
||||
}
|
||||
|
||||
class Main : public QMainWindow {
|
||||
public:
|
||||
Main() :
|
||||
central(this),
|
||||
editor(¢ral),
|
||||
picker(¢ral)
|
||||
{
|
||||
QPopupMenu* file = new QPopupMenu(menuBar());
|
||||
file->insertItem("&Save", &picker, SLOT(save()), CTRL+Key_S);
|
||||
file->insertSeparator();
|
||||
file->insertItem("&Exit", qApp, SLOT(quit()), CTRL+Key_Q);
|
||||
menuBar()->insertItem("&File", file);
|
||||
|
||||
connect( &picker, SIGNAL(pick(const QImage&)),
|
||||
&editor, SLOT(edit(const QImage&)) );
|
||||
connect( &picker, SIGNAL(pickName(const QString&)),
|
||||
statusBar(), SLOT(message(const QString&)) );
|
||||
connect( &editor, SIGNAL(edited(const QImage&)),
|
||||
&picker, SLOT(setCurrent(const QImage&)) );
|
||||
|
||||
setCentralWidget(¢ral);
|
||||
}
|
||||
|
||||
private:
|
||||
QHBox central;
|
||||
TileEditor editor;
|
||||
TilePicker picker;
|
||||
};
|
||||
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
QApplication app(argc,argv);
|
||||
Main m;
|
||||
app.setMainWidget(&m);
|
||||
m.show();
|
||||
return app.exec();
|
||||
}
|
||||
|
||||
#include "tileedit.moc"
|
||||
@@ -0,0 +1,135 @@
|
||||
/* NetHack 3.6 tileedit.h $NHDT-Date: 1432512809 2015/05/25 00:13:29 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ */
|
||||
/* Copyright (c) Warwick Allison, 1999. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
#ifndef QNHTILEEDIT_H
|
||||
#define QNHTILEEDIT_H
|
||||
|
||||
#include <qtabwidget.h>
|
||||
#include <qpixmap.h>
|
||||
#include <qimage.h>
|
||||
#include <qvbox.h>
|
||||
|
||||
class TilePickerTab : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TilePickerTab(const char *basename, int id, QWidget *parent);
|
||||
|
||||
bool save();
|
||||
int numTiles();
|
||||
|
||||
signals:
|
||||
void pick(const QImage &);
|
||||
void pickName(const QString &);
|
||||
|
||||
public slots:
|
||||
void setCurrent(const QImage &);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *);
|
||||
QSize sizeHint() const;
|
||||
void mousePressEvent(QMouseEvent *);
|
||||
|
||||
private:
|
||||
QString filename;
|
||||
int id;
|
||||
int last_pick;
|
||||
int num;
|
||||
QPixmap pixmap;
|
||||
QImage image;
|
||||
};
|
||||
|
||||
class TilePicker : public QTabWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TilePicker(QWidget *parent);
|
||||
|
||||
void setTile(int tilenum, const QImage &);
|
||||
|
||||
signals:
|
||||
void pick(const QImage &);
|
||||
void pickName(const QString &);
|
||||
|
||||
public slots:
|
||||
void setCurrent(const QImage &);
|
||||
void save();
|
||||
};
|
||||
|
||||
class TrivialTileEditor : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TrivialTileEditor(QWidget *parent);
|
||||
const QImage &image() const;
|
||||
|
||||
signals:
|
||||
void edited(const QImage &);
|
||||
void pick(QRgb);
|
||||
|
||||
public slots:
|
||||
void setColor(QRgb);
|
||||
void setImage(const QImage &);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *);
|
||||
void mousePressEvent(QMouseEvent *);
|
||||
void mouseReleaseEvent(QMouseEvent *);
|
||||
void mouseMoveEvent(QMouseEvent *);
|
||||
QSize sizeHint() const;
|
||||
QSize sizeForWidth(int) const;
|
||||
QSizePolicy sizePolicy() const;
|
||||
|
||||
private:
|
||||
void fill(QPainter &painter, QPoint p, uchar from);
|
||||
QImage img;
|
||||
QColor pen;
|
||||
int penpixel;
|
||||
void paintPoint(QPainter &painter, QPoint p);
|
||||
QPoint screenPoint(QPoint) const;
|
||||
QPoint imagePoint(QPoint) const;
|
||||
};
|
||||
|
||||
class TilePalette : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TilePalette(QWidget *parent);
|
||||
~TilePalette();
|
||||
void setFromImage(const QImage &);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *);
|
||||
void mousePressEvent(QMouseEvent *);
|
||||
QSize sizeHint() const;
|
||||
QSizePolicy sizePolicy() const;
|
||||
signals:
|
||||
void pick(QRgb);
|
||||
public slots:
|
||||
void setColor(QRgb);
|
||||
|
||||
private:
|
||||
int num;
|
||||
QRgb *rgb;
|
||||
};
|
||||
|
||||
class TileEditor : public QVBox
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TileEditor(QWidget *parent);
|
||||
|
||||
const QImage &image() const;
|
||||
|
||||
signals:
|
||||
void edited(const QImage &);
|
||||
|
||||
public slots:
|
||||
void edit(const QImage &);
|
||||
|
||||
private:
|
||||
TrivialTileEditor editor;
|
||||
TilePalette palette;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user