1 /* aNetHack 0.0.1 tileedit.cpp $ANH-Date$ $ANH-Branch$:$ANH-Revision$ */
2 /* Copyright (c) Warwick Allison, 1999. */
3 /* aNetHack may be freely redistributed. See license for details. */
5 Build this little utility program if you want to use it to edit the tile
6 files. Move tileedit.cpp and tileedit.h to ../../util, add the
7 3 lines below to the Makefile there and "make tileedit".
9 tileedit: tileedit.cpp $(TEXT_IO)
10 moc -o tileedit.moc tileedit.h
11 $(CC) -o tileedit -I../include -I$(QTDIR)/include -L$(QTDIR)/lib tileedit.cpp $(TEXT_IO) -lqt
16 #include <qapplication.h>
17 #include <qmainwindow.h>
19 #include <qpopupmenu.h>
22 #include <qstatusbar.h>
29 extern const char *FDECL(tilename
, (int, int));
32 #define TILES_ACROSS 20
34 TilePickerTab::TilePickerTab(const char* basename
, int i
, QWidget
* parent
) :
42 for (int real
=0; real
<2; real
++) {
44 image
.create( TILES_ACROSS
*TILE_X
,
45 ((num
+TILES_ACROSS
-1)/TILES_ACROSS
)*TILE_Y
, 32 );
47 if ( !fopen_text_file(filename
.latin1(), RDTMODE
) ) {
51 pixel p
[TILE_Y
][TILE_X
];
52 while ( read_text_tile(p
) ) {
54 int ox
= (index
%TILES_ACROSS
)*TILE_X
;
55 int oy
= (index
/TILES_ACROSS
)*TILE_Y
;
56 for ( int y
=0; y
<TILE_Y
; y
++ ) {
57 QRgb
* rgb
= ((QRgb
*)image
.scanLine(oy
+y
)) + ox
;
58 for ( int x
=0; x
<TILE_X
; x
++ ) {
59 *rgb
++ = qRgb(p
[y
][x
].r
, p
[y
][x
].g
, p
[y
][x
].b
);
70 image
= image
.convertDepth( 8, AvoidDither
);
71 pixmap
.convertFromImage( image
);
74 bool TilePickerTab::save()
76 if ( !fopen_text_file(filename
.latin1(), WRTMODE
) ) {
80 pixel p
[TILE_Y
][TILE_X
];
81 for ( int index
=0; index
< num
; index
++ ) {
82 int ox
= (index
%TILES_ACROSS
)*TILE_X
;
83 int oy
= (index
/TILES_ACROSS
)*TILE_Y
;
84 for ( int y
=0; y
<TILE_Y
; y
++ ) {
85 uchar
* c
= image
.scanLine(oy
+y
) + ox
;
86 for ( int x
=0; x
<TILE_X
; x
++ ) {
87 QRgb rgb
= image
.color(*c
++);
88 p
[y
][x
].r
= qRed(rgb
);
89 p
[y
][x
].g
= qGreen(rgb
);
90 p
[y
][x
].b
= qBlue(rgb
);
98 void TilePickerTab::mousePressEvent(QMouseEvent
* e
)
100 int ox
= e
->x()-e
->x()%TILE_X
;
101 int oy
= e
->y()-e
->y()%TILE_Y
;
102 QImage subimage
= image
.copy(ox
,oy
,TILE_X
,TILE_Y
);
103 if ( e
->button() == RightButton
) {
104 setCurrent(subimage
);
106 last_pick
= ox
/TILE_X
+ oy
/TILE_Y
*TILES_ACROSS
;
109 emit
pickName(tilename(id
, last_pick
));
112 void TilePickerTab::setCurrent(const QImage
& i
)
114 int ox
= last_pick
%TILES_ACROSS
* TILE_X
;
115 int oy
= last_pick
/TILES_ACROSS
* TILE_Y
;
116 bitBlt( &image
, ox
, oy
, &i
);
117 bitBlt( &pixmap
, ox
, oy
, &i
);
118 repaint( ox
, oy
, TILE_X
, TILE_Y
, FALSE
);
121 QSize
TilePickerTab::sizeHint() const
123 return pixmap
.size();
126 void TilePickerTab::paintEvent( QPaintEvent
* )
129 p
.drawPixmap(0,0,pixmap
);
142 TilePicker::TilePicker(QWidget
* parent
) :
145 for (int i
=0; tileset
[i
].name
; i
++) {
146 QString tabname
= tileset
[i
].name
;
147 tabname
[0] = tabname
[0].upper();
148 tileset
[i
].tab
= new TilePickerTab(tileset
[i
].name
,i
+1,this);
149 addTab( tileset
[i
].tab
, tabname
);
150 connect( tileset
[i
].tab
, SIGNAL(pick(const QImage
&)),
151 this, SIGNAL(pick(const QImage
&)) );
152 connect( tileset
[i
].tab
, SIGNAL(pickName(const QString
&)),
153 this, SIGNAL(pickName(const QString
&)) );
157 void TilePicker::setCurrent(const QImage
& i
)
159 ((TilePickerTab
*)currentPage())->setCurrent(i
);
162 void TilePicker::save()
164 for (int i
=0; tileset
[i
].tab
; i
++) {
165 tileset
[i
].tab
->save();
169 TrivialTileEditor::TrivialTileEditor( QWidget
* parent
) :
174 const QImage
& TrivialTileEditor::image() const
179 void TrivialTileEditor::setColor( QRgb rgb
)
183 penpixel
<img
.numColors()-1 && (img
.color(penpixel
)&0xffffff)!=(pen
.rgb()&0xffffff);
188 void TrivialTileEditor::setImage( const QImage
& i
)
191 setColor(pen
.rgb()); // update penpixel
195 void TrivialTileEditor::paintEvent( QPaintEvent
* e
)
198 QPoint tl
= imagePoint(r
.topLeft());
199 QPoint br
= imagePoint(r
.bottomRight());
200 r
= QRect(tl
,br
).intersect(img
.rect());
201 QPainter
painter(this);
202 for (int y
=r
.top(); y
<=r
.bottom(); y
++) {
203 for (int x
=r
.left(); x
<=r
.right(); x
++) {
204 paintPoint(painter
,QPoint(x
,y
));
209 void TrivialTileEditor::paintPoint(QPainter
& painter
, QPoint p
)
211 QPoint p1
= screenPoint(p
);
212 QPoint p2
= screenPoint(p
+QPoint(1,1));
213 QColor c
= img
.color(img
.scanLine(p
.y())[p
.x()]);
214 painter
.fillRect(QRect(p1
,p2
-QPoint(1,1)), c
);
217 void TrivialTileEditor::mousePressEvent(QMouseEvent
* e
)
219 QPoint p
= imagePoint(e
->pos());
220 if ( !img
.rect().contains(p
) )
222 uchar
& pixel
= img
.scanLine(p
.y())[p
.x()];
223 if ( e
->button() == LeftButton
) {
225 QPainter
painter(this);
226 paintPoint(painter
,p
);
227 } else if ( e
->button() == RightButton
) {
228 emit
pick( img
.color(pixel
) );
229 } else if ( e
->button() == MidButton
) {
230 QPainter
painter(this);
231 if ( pixel
!= penpixel
)
232 fill(painter
,p
,pixel
);
236 void TrivialTileEditor::fill(QPainter
& painter
, QPoint p
, uchar from
)
238 if ( img
.rect().contains(p
) ) {
239 uchar
& pixel
= img
.scanLine(p
.y())[p
.x()];
240 if ( pixel
== from
) {
242 paintPoint(painter
,p
);
243 fill(painter
, p
+QPoint(-1,0), from
);
244 fill(painter
, p
+QPoint(+1,0), from
);
245 fill(painter
, p
+QPoint(0,-1), from
);
246 fill(painter
, p
+QPoint(0,+1), from
);
251 void TrivialTileEditor::mouseReleaseEvent(QMouseEvent
* e
)
253 emit
edited(image());
256 void TrivialTileEditor::mouseMoveEvent(QMouseEvent
* e
)
258 QPoint p
= imagePoint(e
->pos());
259 if ( !img
.rect().contains(p
) )
261 uchar
& pixel
= img
.scanLine(p
.y())[p
.x()];
263 QPainter
painter(this);
264 paintPoint(painter
,p
);
267 QPoint
TrivialTileEditor::imagePoint(QPoint p
) const
269 return QPoint(p
.x()*TILE_X
/width(), p
.y()*TILE_Y
/height());
272 QPoint
TrivialTileEditor::screenPoint(QPoint p
) const
274 return QPoint(p
.x()*width()/TILE_X
, p
.y()*height()/TILE_Y
);
277 QSizePolicy
TrivialTileEditor::sizePolicy() const
279 return QSizePolicy( QSizePolicy::Expanding
, QSizePolicy::Expanding
, TRUE
);
282 QSize
TrivialTileEditor::sizeHint() const
284 return sizeForWidth(-1);
287 QSize
TrivialTileEditor::sizeForWidth(int w
) const
290 return QSize(TILE_X
*32,TILE_Y
*32);
292 return QSize(w
,w
*TILE_Y
/TILE_X
);
296 TilePalette::TilePalette( QWidget
* parent
) :
303 TilePalette::~TilePalette()
308 void TilePalette::setFromImage( const QImage
& i
)
312 memcpy(rgb
, i
.colorTable(), num
*sizeof(QRgb
));
316 void TilePalette::setColor(QRgb c
)
318 for (int i
=0; i
<num
; i
++)
325 QSizePolicy
TilePalette::sizePolicy() const
327 return QSizePolicy( QSizePolicy::Minimum
, QSizePolicy::Minimum
, FALSE
);
330 QSize
TilePalette::sizeHint() const
332 return QSize(num
*16,16);
335 void TilePalette::paintEvent( QPaintEvent
* )
338 for (int i
=0; i
<num
; i
++) {
339 int x1
= width()*i
/num
;
340 int x2
= width()*(i
+1)/num
;
341 p
.fillRect(x1
,0,x2
-x1
,height(),QColor(rgb
[i
]));
345 void TilePalette::mousePressEvent(QMouseEvent
* e
)
347 int c
= e
->x()*num
/width();
351 TileEditor::TileEditor(QWidget
* parent
) :
356 connect( &palette
, SIGNAL(pick(QRgb
)),
357 &editor
, SLOT(setColor(QRgb
)) );
358 connect( &editor
, SIGNAL(pick(QRgb
)),
359 &palette
, SLOT(setColor(QRgb
)) );
360 connect( &editor
, SIGNAL(edited(const QImage
&)),
361 this, SIGNAL(edited(const QImage
&)) );
364 void TileEditor::edit(const QImage
& i
)
367 palette
.setFromImage(i
);
370 const QImage
& TileEditor::image() const
372 return editor
.image();
375 class Main
: public QMainWindow
{
382 QPopupMenu
* file
= new QPopupMenu(menuBar());
383 file
->insertItem("&Save", &picker
, SLOT(save()), CTRL
+Key_S
);
384 file
->insertSeparator();
385 file
->insertItem("&Exit", qApp
, SLOT(quit()), CTRL
+Key_Q
);
386 menuBar()->insertItem("&File", file
);
388 connect( &picker
, SIGNAL(pick(const QImage
&)),
389 &editor
, SLOT(edit(const QImage
&)) );
390 connect( &picker
, SIGNAL(pickName(const QString
&)),
391 statusBar(), SLOT(message(const QString
&)) );
392 connect( &editor
, SIGNAL(edited(const QImage
&)),
393 &picker
, SLOT(setCurrent(const QImage
&)) );
395 setCentralWidget(¢ral
);
404 main(int argc
, char** argv
)
406 QApplication
app(argc
,argv
);
408 app
.setMainWidget(&m
);
413 #include "tileedit.moc"