initial 1.3.0

This commit is contained in:
2019-05-01 17:46:38 -04:00
commit ad86bc2a30
418 changed files with 34837 additions and 0 deletions

266
src/agicommands.cpp Normal file
View File

@@ -0,0 +1,266 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include "agicommands.h"
const char *ArgTypePrefix[9] = {"","v","f","m","o","i","s","w","c"};
const char *ArgTypeName[9] = {"number","var","flag","message","object",
"inventory item","string","word","controller"};
CommandStruct TestCommand[19] = {
{ "", 0 , { 0,0,0,0,0,0,0 } }, //dummy
{ "equaln", 2, { atVar,atNum,0,0,0,0,0 } },
{ "equalv", 2, { atVar,atVar,0,0,0,0,0 } },
{ "lessn", 2, { atVar,atNum,0,0,0,0,0 } },
{ "lessv", 2, { atVar,atVar,0,0,0,0,0 } },
{ "greatern", 2, { atVar,atNum,0,0,0,0,0 } },
{ "greaterv", 2, { atVar,atVar,0,0,0,0,0 } },
{ "isset", 1, { atFlag,0,0,0,0,0,0 } },
{ "issetv", 1, { atVar,0,0,0,0,0,0 } },
{ "has", 1, { atIObj,0,0,0,0,0,0 } },
{ "obj.in.room", 2, { atIObj,atVar,0,0,0,0,0 } },
{ "posn", 5, { atSObj,atNum,atNum,atNum,atNum,0,0 } },
{ "controller", 1, { atCtrl,0,0,0,0,0,0 } },
{ "have.key", 0, { 0,0,0,0,0,0,0 } },
{ "said", 0, { 0,0,0,0,0,0,0 } }, // special command so we don't need to set the right argument types for it
{ "compare.strings", 2, { atStr,atStr,0,0,0,0,0 } },
{ "obj.in.box", 5, { atSObj,atNum,atNum,atNum,atNum,0,0 } },
{ "center.posn", 5, { atSObj,atNum,atNum,atNum,atNum,0,0 } },
{ "right.posn", 5, { atSObj,atNum,atNum,atNum,atNum,0,0 } }
};
CommandStruct AGICommand[182] = {
{ "return", 0, { 0,0,0,0,0,0,0 } },
{ "increment", 1, { atVar,0,0,0,0,0,0 } },
{ "decrement", 1, { atVar,0,0,0,0,0,0 } },
{ "assignn", 2, { atVar,atNum,0,0,0,0,0 } },
{ "assignv", 2, { atVar,atVar,0,0,0,0,0 } },
{ "addn", 2, { atVar,atNum,0,0,0,0,0 } },
{ "addv", 2, { atVar,atVar,0,0,0,0,0 } },
{ "subn", 2, { atVar,atNum,0,0,0,0,0 } },
{ "subv", 2, { atVar,atVar,0,0,0,0,0 } },
{ "lindirectv", 2, { atVar,atVar,0,0,0,0,0 } },
{ "rindirect", 2, { atVar,atVar,0,0,0,0,0 } },
{ "lindirectn", 2, { atVar,atNum,0,0,0,0,0 } },
{ "set", 1, { atFlag,0,0,0,0,0,0 } },
{ "reset", 1, { atFlag,0,0,0,0,0,0 } },
{ "toggle", 1, { atFlag,0,0,0,0,0,0 } },
{ "set.v", 1, { atVar,0,0,0,0,0,0 } },
{ "reset.v", 1, { atVar,0,0,0,0,0,0 } },
{ "toggle.v", 1, { atVar,0,0,0,0,0,0 } },
{ "new.room", 1, { atNum,0,0,0,0,0,0 } },
{ "new.room.v", 1, { atVar,0,0,0,0,0,0 } },
{ "load.logics", 1, { atNum,0,0,0,0,0,0 } },
{ "load.logics.v", 1, { atVar,0,0,0,0,0,0 } },
{ "call", 1, { atNum,0,0,0,0,0,0 } },
{ "call.v", 1, { atVar,0,0,0,0,0,0 } },
{ "load.pic", 1, { atVar,0,0,0,0,0,0 } },
{ "draw.pic", 1, { atVar,0,0,0,0,0,0 } },
{ "show.pic", 0, { 0,0,0,0,0,0,0 } },
{ "discard.pic", 1, { atVar,0,0,0,0,0,0 } },
{ "overlay.pic", 1, { atVar,0,0,0,0,0,0 } },
{ "show.pri.screen", 0, { 0,0,0,0,0,0,0 } },
{ "load.view", 1, { atNum,0,0,0,0,0,0 } },
{ "load.view.v", 1, { atVar,0,0,0,0,0,0 } },
{ "discard.view", 1, { atNum,0,0,0,0,0,0 } },
{ "animate.obj", 1, { atSObj,0,0,0,0,0,0 } },
{ "unanimate.all", 0, { 0,0,0,0,0,0,0 } },
{ "draw", 1, { atSObj,0,0,0,0,0,0 } },
{ "erase", 1, { atSObj,0,0,0,0,0,0 } },
{ "position", 3, { atSObj,atNum,atNum,0,0,0,0 } },
{ "position.v", 3, { atSObj,atVar,atVar,0,0,0,0 } },
{ "get.posn", 3, { atSObj,atVar,atVar,0,0,0,0 } },
{ "reposition", 3, { atSObj,atVar,atVar,0,0,0,0 } },
{ "set.view", 2, { atSObj,atNum,0,0,0,0,0 } },
{ "set.view.v", 2, { atSObj,atVar,0,0,0,0,0 } },
{ "set.loop", 2, { atSObj,atNum,0,0,0,0,0 } },
{ "set.loop.v", 2, { atSObj,atVar,0,0,0,0,0 } },
{ "fix.loop", 1, { atSObj,0,0,0,0,0,0 } },
{ "release.loop", 1, { atSObj,0,0,0,0,0,0 } },
{ "set.cel", 2, { atSObj,atNum,0,0,0,0,0 } },
{ "set.cel.v", 2, { atSObj,atVar,0,0,0,0,0 } },
{ "last.cel", 2, { atSObj,atVar,0,0,0,0,0 } },
{ "current.cel", 2, { atSObj,atVar,0,0,0,0,0 } },
{ "current.loop", 2, { atSObj,atVar,0,0,0,0,0 } },
{ "current.view", 2, { atSObj,atVar,0,0,0,0,0 } },
{ "number.of.loops", 2, { atSObj,atVar,0,0,0,0,0 } },
{ "set.priority", 2, { atSObj,atNum,0,0,0,0,0 } },
{ "set.priority.v", 2, { atSObj,atVar,0,0,0,0,0 } },
{ "release.priority", 1, { atSObj,0,0,0,0,0,0 } },
{ "get.priority", 2, { atSObj,atVar,0,0,0,0,0 } },
{ "stop.update", 1, { atSObj,0,0,0,0,0,0 } },
{ "start.update", 1, { atSObj,0,0,0,0,0,0 } },
{ "force.update", 1, { atSObj,0,0,0,0,0,0 } },
{ "ignore.horizon", 1, { atSObj,0,0,0,0,0,0 } },
{ "observe.horizon", 1, { atSObj,0,0,0,0,0,0 } },
{ "set.horizon", 1, { atNum,0,0,0,0,0,0 } },
{ "object.on.water", 1, { atSObj,0,0,0,0,0,0 } },
{ "object.on.land", 1, { atSObj,0,0,0,0,0,0 } },
{ "object.on.anything", 1, { atSObj,0,0,0,0,0,0 } },
{ "ignore.objs", 1, { atSObj,0,0,0,0,0,0 } },
{ "observe.objs", 1, { atSObj,0,0,0,0,0,0 } },
{ "distance", 3, { atSObj,atSObj,atVar,0,0,0,0 } },
{ "stop.cycling", 1, { atSObj,0,0,0,0,0,0 } },
{ "start.cycling", 1, { atSObj,0,0,0,0,0,0 } },
{ "normal.cycle", 1, { atSObj,0,0,0,0,0,0 } },
{ "end.of.loop", 2, { atSObj,atFlag,0,0,0,0,0 } },
{ "reverse.cycle", 1, { atSObj,0,0,0,0,0,0 } },
{ "reverse.loop", 2, { atSObj,atFlag,0,0,0,0,0 } },
{ "cycle.time", 2, { atSObj,atVar,0,0,0,0,0 } }, // arg2 Num???
{ "stop.motion", 1, { atSObj,0,0,0,0,0,0 } },
{ "start.motion", 1, { atSObj,0,0,0,0,0,0 } },
{ "step.size", 2, { atSObj,atVar,0,0,0,0,0 } }, // arg2 Num???
{ "step.time", 2, { atSObj,atVar,0,0,0,0,0 } }, // arg2 Num???
{ "move.obj", 5, { atSObj,atNum,atNum,atNum,atFlag,0,0 } },
{ "move.obj.v", 5, { atSObj,atVar,atVar,atNum,atFlag,0,0 } }, // arg 3 var???
{ "follow.ego", 3, { atSObj,atNum,atFlag,0,0,0,0 } },
{ "wander", 1, { atSObj,0,0,0,0,0,0 } },
{ "normal.motion", 1, { atSObj,0,0,0,0,0,0 } },
{ "set.dir", 2, { atSObj,atVar,0,0,0,0,0 } },
{ "get.dir", 2, { atSObj,atVar,0,0,0,0,0 } },
{ "ignore.blocks", 1, { atSObj,0,0,0,0,0,0 } },
{ "observe.blocks", 1, { atSObj,0,0,0,0,0,0 } },
{ "block", 4, { atNum,atNum,atNum,atNum,0,0,0 } },
{ "unblock", 0, { 0,0,0,0,0,0,0 } },
{ "get", 1, { atIObj,0,0,0,0,0,0 } },
{ "get.v", 1, { atVar,0,0,0,0,0,0 } },
{ "drop", 1, { atIObj,0,0,0,0,0,0 } },
{ "put", 2, { atIObj,atVar,0,0,0,0,0 } },
{ "put.v", 2, { atVar,atVar,0,0,0,0,0 } },
{ "get.room.v", 2, { atVar,atVar,0,0,0,0,0 } },
{ "load.sound", 1, { atNum,0,0,0,0,0,0 } },
{ "sound", 2, { atNum,atFlag,0,0,0,0,0 } },
{ "stop.sound", 0, { 0,0,0,0,0,0,0 } },
{ "print", 1, { atMsg,0,0,0,0,0,0 } },
{ "print.v", 1, { atVar,0,0,0,0,0,0 } },
{ "display", 3, { atNum,atNum,atMsg,0,0,0,0 } },
{ "display.v", 3, { atVar,atVar,atVar,0,0,0,0 } },
{ "clear.lines", 3, { atNum,atNum,atNum,0,0,0,0 } },
{ "text.screen", 0, { 0,0,0,0,0,0,0 } },
{ "graphics", 0, { 0,0,0,0,0,0,0 } },
{ "set.cursor.char", 1, { atMsg,0,0,0,0,0,0 } },
{ "set.text.attribute", 2, { atNum,atNum,0,0,0,0,0 } },
{ "shake.screen", 1, { atNum,0,0,0,0,0,0 } },
{ "configure.screen", 3, { atNum,atNum,atNum,0,0,0,0 } },
{ "status.line.on", 0, { 0,0,0,0,0,0,0 } },
{ "status.line.off", 0, { 0,0,0,0,0,0,0 } },
{ "set.string", 2, { atStr,atMsg,0,0,0,0,0 } },
{ "get.string", 5, { atStr,atMsg,atNum,atNum,atNum,0,0 } },
{ "word.to.string", 2, { atWord,atStr,0,0,0,0,0 } },
{ "parse", 1, { atStr,0,0,0,0,0,0 } },
{ "get.num", 2, { atMsg,atVar,0,0,0,0,0 } },
{ "prevent.input", 0, { 0,0,0,0,0,0,0 } },
{ "accept.input", 0, { 0,0,0,0,0,0,0 } },
{ "set.key", 3, { atNum,atNum,atCtrl,0,0,0,0 } },
{ "add.to.pic", 7, { atNum,atNum,atNum,atNum,atNum,atNum,atNum } },
{ "add.to.pic.v", 7, { atVar,atVar,atVar,atVar,atVar,atVar,atVar } },
{ "status", 0, { 0,0,0,0,0,0,0 } },
{ "save.game", 0, { 0,0,0,0,0,0,0 } },
{ "restore.game", 0, { 0,0,0,0,0,0,0 } },
{ "init.disk", 0, { 0,0,0,0,0,0,0 } },
{ "restart.game", 0, { 0,0,0,0,0,0,0 } },
{ "show.obj", 1, { atNum,0,0,0,0,0,0 } },
{ "random", 3, { atNum,atNum,atVar,0,0,0,0 } },
{ "program.control", 0, { 0,0,0,0,0,0,0 } },
{ "player.control", 0, { 0,0,0,0,0,0,0 } },
{ "obj.status.v", 1, { atVar,0,0,0,0,0,0 } },
{ "quit", 1, { atNum,0,0,0,0,0,0 } }, // 0 args for 2.089
{ "show.mem", 0, { 0,0,0,0,0,0,0 } },
{ "pause", 0, { 0,0,0,0,0,0,0 } },
{ "echo.line", 0, { 0,0,0,0,0,0,0 } },
{ "cancel.line", 0, { 0,0,0,0,0,0,0 } },
{ "init.joy", 0, { 0,0,0,0,0,0,0 } },
{ "toggle.monitor", 0, { 0,0,0,0,0,0,0 } },
{ "version", 0, { 0,0,0,0,0,0,0 } },
{ "script.size", 1, { atNum,0,0,0,0,0,0 } },
{ "set.game.id", 1, { atMsg,0,0,0,0,0,0 } },
{ "log", 1, { atMsg,0,0,0,0,0,0 } },
{ "set.scan.start", 0, { 0,0,0,0,0,0,0 } },
{ "reset.scan.start", 0, { 0,0,0,0,0,0,0 } },
{ "reposition.to", 3, { atSObj,atNum,atNum,0,0,0,0 } },
{ "reposition.to.v", 3, { atSObj,atVar,atVar,0,0,0,0 } },
{ "trace.on", 0, { 0,0,0,0,0,0,0 } },
{ "trace.info", 3, { atNum,atNum,atNum,0,0,0,0 } },
{ "print.at", 4, { atMsg,atNum,atNum,atNum,0,0,0 } }, // 3 args before 2.440
{ "print.at.v", 4, { atMsg,atVar,atVar,atVar,0,0,0 } }, // 3 args before 2.440
{ "discard.view.v", 1, { atVar,0,0,0,0,0,0 } },
{ "clear.text.rect", 5, { atNum,atNum,atNum,atNum,atNum,0,0 } },
{ "set.upper.left", 2, { 0,0,0,0,0,0,0 } }, // ?????
{ "set.menu", 1, { atMsg,0,0,0,0,0,0 } },
{ "set.menu.item", 2, { atMsg,atCtrl,0,0,0,0,0 } },
{ "submit.menu", 0, { 0,0,0,0,0,0,0 } },
{ "enable.item", 1, { atCtrl,0,0,0,0,0,0 } },
{ "disable.item", 1, { atCtrl,0,0,0,0,0,0 } },
{ "menu.input", 0, { 0,0,0,0,0,0,0 } },
{ "show.obj.v", 1, { atVar,0,0,0,0,0,0 } },
{ "open.dialogue", 0, { 0,0,0,0,0,0,0 } },
{ "close.dialogue", 0, { 0,0,0,0,0,0,0 } },
{ "mul.n", 2, { atVar,atNum,0,0,0,0,0 } },
{ "mul.v", 2, { atVar,atVar,0,0,0,0,0 } },
{ "div.n", 2, { atVar,atNum,0,0,0,0,0 } },
{ "div.v", 2, { atVar,atVar,0,0,0,0,0 } },
{ "close.window", 0, { 0,0,0,0,0,0,0 } },
// The formerly unknown commands
{ "set.simple", 1, {0,0,0,0,0,0,0 } }, // unknown 170
{ "push.script", 0, {0,0,0,0,0,0,0 } }, // unknown 171
{ "pop.script", 0, {0,0,0,0,0,0,0 } }, // unknown 172
{ "hold.key", 0, {0,0,0,0,0,0,0 } }, // unknown 173
{ "set.pri.base", 1, {0,0,0,0,0,0,0 } }, // unknown 174
{ "discard.sound", 1, {0,0,0,0,0,0,0 } }, // unknown 175
{ "hide.mouse", 0, {0,0,0,0,0,0,0 } }, // unknown 176 - 1 arg for 3.002.086
{ "allow.menu", 1, {0,0,0,0,0,0,0 } }, // unknown 177
{ "show.mouse", 0, {0,0,0,0,0,0,0 } }, // unknown 178
{ "fence.mouse", 4, {0,0,0,0,0,0,0 } }, // unknown 179
{ "mouse.posn", 2, {0,0,0,0,0,0,0 } }, // unknown 180
{ "release.key", 0, {0,0,0,0,0,0,0 } } // unknown 181
};
int NumAGICommands = 181; // not counting return()
void CorrectCommands(double VerNum)
{
if(VerNum <= 2.089){
AGICommand[134].NumArgs = 0; //quit
}
if(VerNum < 2.400){
AGICommand[151].NumArgs = 3; // print.at
AGICommand[152].NumArgs = 3; // print.at.v
}
if(VerNum <= 3.002086){
AGICommand[176].NumArgs = 1;
}
if(VerNum <= 2.089)NumAGICommands = 155;
else if (VerNum <= 2.272)NumAGICommands = 161;
else if (VerNum <= 2.440)NumAGICommands = 169;
else if (VerNum <= 2.917)NumAGICommands = 173;
else if (VerNum <= 2.936)NumAGICommands = 175;
else if (VerNum <= 3.002086)NumAGICommands = 177;
else NumAGICommands = 181;
}

53
src/agicommands.h Normal file
View File

@@ -0,0 +1,53 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef AGI_COMMANDS_H
#define AGI_COMMANDS_H
//argument types
#define atNum 0
#define atVar 1
#define atFlag 2
#define atMsg 3
#define atSObj 4
#define atIObj 5
#define atStr 6
#define atWord 7
#define atCtrl 8
extern const char *ArgTypePrefix[9] ;
extern const char *ArgTypeName[9] ;
typedef struct {
const char *Name;
char NumArgs;
char argTypes[7];
}CommandStruct;
#define NumTestCommands 18
extern int NumAGICommands; //changes in different AGI interpreter versions
extern CommandStruct TestCommand[19]; //tests for different flags, etc
extern CommandStruct AGICommand[182]; //all the other
extern void CorrectCommands(double VerNum);
#endif

291
src/agiplay.cpp Normal file
View File

@@ -0,0 +1,291 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
* AGI player for i386 Linux and OSS
* Written by Claudio Matsuoka <claudio@helllabs.org>
* Sun Mar 21 13:27:35 EST 1999
*
* Based on the format of the AGI SOUND resource as described by
* Lance Ewing <lance.e@ihug.co.nz>
*
*
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef _WIN32
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <q3progressdialog.h>
#endif
#include "game.h"
#include "menu.h"
#ifdef __linux__
#include <sys/soundcard.h>
#define WAVEFORM_SIZE 64
#define ENV_DECAY 800
#define ENV_SUSTAIN 160
struct agi_note {
unsigned char dur_lo;
unsigned char dur_hi;
unsigned char frq_0;
unsigned char frq_1;
unsigned char vol;
};
struct channel_info {
struct agi_note *ptr;
int end;
int freq;
int phase;
int vol;
int env;
int timer;
};
static int audio_fd;
static short *buffer;
static struct channel_info chn[4];
static int waveform[WAVEFORM_SIZE] = {
0, 8, 16, 24, 32, 40, 48, 56,
64, 72, 80, 88, 96, 104, 112, 120,
128, 136, 144, 152, 160, 168, 176, 184,
192, 200, 208, 216, 224, 232, 240, 255,
0,-248,-240,-232,-224,-216,-208,-200,
-192,-184,-176,-168,-160,-152,-144,-136,
-128,-120,-112,-104, -96, -88, -80, -72,
-64, -56, -48, -40, -32, -24, -16, -8 /* Ramp up */
};
int init_sound ()
{
int i;
/* Set sound device to 16 bit, 22 kHz mono */
if ((audio_fd = open ("/dev/audio", O_WRONLY)) == -1)
return -1;
i = AFMT_S16_NE; /* Native endian */
ioctl (audio_fd, SNDCTL_DSP_SETFMT, &i);
i = 0;
ioctl (audio_fd, SNDCTL_DSP_STEREO, &i);
i = 22000;
ioctl (audio_fd, SNDCTL_DSP_SPEED, &i);
buffer = (short *)calloc (2, 2048);
return 0;
}
void close_sound ()
{
free (buffer);
close (audio_fd);
}
void mix_channels (int s)
{
register int i, p;
int c, b, m;
/* Size is in 16-bit samples */
memset (buffer, 0, s << 1);
/* Now build the sound for each channel */
for (c = 0; c < 3; c++) {
if (!chn[c].vol)
continue;
p = chn[c].phase;
m = chn[c].vol * chn[c].env >> 16;
/* Build a sound buffer. The format is signed 16 bit mono,
* native-endian samples */
for (i = 0; i < s; i++) {
/* Interpolate to get a sample from the waveform */
b = waveform[p >> 8] + (((waveform[((p >> 8) + 1) % WAVEFORM_SIZE] -
waveform[p >> 8]) * (p & 0xff)) >> 8);
/* Add to the buffer, processing the envelope */
buffer[i] += (b * m) >> 3;
p += 11860 * 4 / chn[c].freq;
p %= WAVEFORM_SIZE << 8;
}
/* Update the channel phase */
chn[c].phase = p;
/* Update the envelope */
if (chn[c].env > chn[c].vol * ENV_SUSTAIN)
chn[c].env -= ENV_DECAY;
}
}
void dump_buffer (int i)
{
for (i <<= 1; i -= write (audio_fd, buffer, i); ) {}
}
void stop_note (int i)
{
chn[i].vol = 0;
}
void play_note (int i, int freq, int vol)
{
chn[i].freq = freq;
chn[i].phase = 0;
chn[i].vol = vol;
chn[i].env = 0x10000;
}
void play_song (unsigned char *song, int size)
{
int i, playing;
/* Initialize channel pointers */
for (i = 0; i < 4; i++) {
chn[i].ptr = (struct agi_note *)(song + (song[i << 1] | (song[(i << 1) + 1] << 8)));
chn[i].timer = 0;
chn[i].end = 0;
}
int step=0;
Q3ProgressDialog progress( "Playing...", "Cancel", (size+16)/5,0, 0, TRUE );
progress.setMinimumDuration(0);
for (playing = 1; playing; ) {
int freq;
for (playing = i = 0; i < 4; i++) {
playing |= !chn[i].end;
if (chn[i].end)
continue;
if ((--chn[i].timer) <= 0) {
if (chn[i].ptr >= (struct agi_note *)song + size)
break;
stop_note (i);
freq = ((chn[i].ptr->frq_0 & 0x3f) << 4)
| (int)(chn[i].ptr->frq_1 & 0x0f);
if (freq) {
unsigned char v = chn[i].ptr->vol & 0x0f;
play_note (i, freq, v == 0xf ? 0 : 0xff - (v << 1));
}
chn[i].timer = ((int)chn[i].ptr->dur_hi << 8) |
chn[i].ptr->dur_lo;
if (chn[i].timer == 0xffff) {
chn[i].end = 1;
chn[i].vol = 0;
}
chn[i].ptr++;
progress.setProgress( step++ );
if ( progress.wasCancelled() ){
playing=false;
break;
}
}
}
mix_channels (400);
dump_buffer (400);
}
}
#endif
void play_sound(int ResNum)
{
#ifdef __linux__
if (init_sound () != 0) {
menu->errmes("Can't initialize sound !");
return;
}
int err = game->ReadResource(SOUND,ResNum);
if(err)return;
play_song(ResourceData.Data,ResourceData.Size);
close_sound ();
#else
menu->errmes("Sound currently works only under Linux !");
return;
#endif
}
void play_sound(char *filename)
{
#ifdef __linux__
if (init_sound () != 0) {
menu->errmes("Can't initialize sound !");
return;
}
FILE *fptr=fopen(filename,"rb");
if(fptr==NULL){
menu->errmes("Can't open file %s !",filename);
return;
}
struct stat buf;
fstat(fileno(fptr),&buf);
ResourceData.Size=buf.st_size;
fread(ResourceData.Data,ResourceData.Size,1,fptr);
fclose(fptr);
play_song(ResourceData.Data,ResourceData.Size);
close_sound ();
#else
menu->errmes("Sound currently works only under Linux !");
return;
#endif
}

BIN
src/agistudio.aps Normal file

Binary file not shown.

670
src/agistudio.dsp Normal file
View File

@@ -0,0 +1,670 @@
# Microsoft Developer Studio Project File - Name="agistudio" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Application" 0x0101
CFG=agistudio - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "agistudio.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "agistudio.mak" CFG="agistudio - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "agistudio - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "agistudio - Win32 Debug" (based on "Win32 (x86) Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "agistudio - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir ".."
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MDd /W3 /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FD /c
# ADD CPP /nologo /MDd /W3 /O1 /I "$(QTDIR)\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "QT_DLL" /D "QT_THREAD_SUPPORT" /D "UNICODE" /D "NO_DEBUG" /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib imm32.lib winmm.lib wsock32.lib /nologo /subsystem:windows /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib imm32.lib winmm.lib wsock32.lib imm32.lib wsock32.lib winmm.lib $(QTDIR)\lib\qt-mt230nc.lib $(QTDIR)\lib\qtmain.lib /nologo /subsystem:windows /machine:I386
!ELSEIF "$(CFG)" == "agistudio - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "$(QTDIR)\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "QT_DLL" /D "QT_THREAD_SUPPORT" /D "UNICODE" /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib imm32.lib winmm.lib wsock32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib imm32.lib winmm.lib wsock32.lib imm32.lib wsock32.lib winmm.lib $(QTDIR)\lib\qt-mt230nc.lib $(QTDIR)\lib\qtmain.lib /nologo /subsystem:windows /debug /machine:I386 /nodefaultlib:"libc" /nodefaultlib:"msvcrt" /pdbtype:sept
# SUBTRACT LINK32 /pdb:none
!ENDIF
# Begin Target
# Name "agistudio - Win32 Release"
# Name "agistudio - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\agicommands.cpp
# End Source File
# Begin Source File
SOURCE=.\agiplay.cpp
# End Source File
# Begin Source File
SOURCE=.\bpicture.cpp
# End Source File
# Begin Source File
SOURCE=.\dir.cpp
# End Source File
# Begin Source File
SOURCE=.\game.cpp
# End Source File
# Begin Source File
SOURCE=.\helpwindow.cpp
# End Source File
# Begin Source File
SOURCE=.\linklist.cpp
# End Source File
# Begin Source File
SOURCE=.\logcompile.cpp
# End Source File
# Begin Source File
SOURCE=.\logdecode.cpp
# End Source File
# Begin Source File
SOURCE=.\logedit.cpp
# End Source File
# Begin Source File
SOURCE=.\logic.cpp
# End Source File
# Begin Source File
SOURCE=.\main.cpp
# End Source File
# Begin Source File
SOURCE=.\menu.cpp
# End Source File
# Begin Source File
SOURCE=.\moc_dir.cpp
# End Source File
# Begin Source File
SOURCE=.\moc_helpwindow.cpp
# End Source File
# Begin Source File
SOURCE=.\moc_logedit.cpp
# End Source File
# Begin Source File
SOURCE=.\moc_menu.cpp
# End Source File
# Begin Source File
SOURCE=.\moc_objedit.cpp
# End Source File
# Begin Source File
SOURCE=.\moc_options.cpp
# End Source File
# Begin Source File
SOURCE=.\moc_picedit.cpp
# End Source File
# Begin Source File
SOURCE=.\moc_preview.cpp
# End Source File
# Begin Source File
SOURCE=.\moc_resources.cpp
# End Source File
# Begin Source File
SOURCE=.\moc_roomgen.cpp
# End Source File
# Begin Source File
SOURCE=.\moc_viewedit.cpp
# End Source File
# Begin Source File
SOURCE=.\moc_wordsedit.cpp
# End Source File
# Begin Source File
SOURCE=.\moc_wutil.cpp
# End Source File
# Begin Source File
SOURCE=.\object.cpp
# End Source File
# Begin Source File
SOURCE=.\objedit.cpp
# End Source File
# Begin Source File
SOURCE=.\options.cpp
# End Source File
# Begin Source File
SOURCE=.\picedit.cpp
# End Source File
# Begin Source File
SOURCE=.\picture.cpp
# End Source File
# Begin Source File
SOURCE=.\preview.cpp
# End Source File
# Begin Source File
SOURCE=.\resources.cpp
# End Source File
# Begin Source File
SOURCE=.\roomgen.cpp
# End Source File
# Begin Source File
SOURCE=.\util.cpp
# End Source File
# Begin Source File
SOURCE=.\view.cpp
# End Source File
# Begin Source File
SOURCE=.\viewedit.cpp
# End Source File
# Begin Source File
SOURCE=.\words.cpp
# End Source File
# Begin Source File
SOURCE=.\wordsedit.cpp
# End Source File
# Begin Source File
SOURCE=.\wutil.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\agicommands.h
# End Source File
# Begin Source File
SOURCE=.\dir.h
!IF "$(CFG)" == "agistudio - Win32 Release"
# Begin Custom Build - Moc'ing dir.h...
InputPath=.\dir.h
"moc_dir.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
%QTDIR%\bin\moc.exe dir.h -o moc_dir.cpp
# End Custom Build
!ELSEIF "$(CFG)" == "agistudio - Win32 Debug"
# Begin Custom Build - Moc'ing dir.h...
InputPath=.\dir.h
"moc_dir.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
%QTDIR%\bin\moc.exe dir.h -o moc_dir.cpp
# End Custom Build
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\game.h
# End Source File
# Begin Source File
SOURCE=.\global.h
# End Source File
# Begin Source File
SOURCE=.\helpwindow.h
!IF "$(CFG)" == "agistudio - Win32 Release"
# Begin Custom Build - Moc'ing helpwindow.h...
InputPath=.\helpwindow.h
"moc_helpwindow.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
%QTDIR%\bin\moc.exe helpwindow.h -o moc_helpwindow.cpp
# End Custom Build
!ELSEIF "$(CFG)" == "agistudio - Win32 Debug"
# Begin Custom Build - Moc'ing helpwindow.h...
InputPath=.\helpwindow.h
"moc_helpwindow.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
%QTDIR%\bin\moc.exe helpwindow.h -o moc_helpwindow.cpp
# End Custom Build
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\linklist.h
# End Source File
# Begin Source File
SOURCE=.\logedit.h
!IF "$(CFG)" == "agistudio - Win32 Release"
# Begin Custom Build - Moc'ing logedit.h...
InputPath=.\logedit.h
"moc_logedit.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
%QTDIR%\bin\moc.exe logedit.h -o moc_logedit.cpp
# End Custom Build
!ELSEIF "$(CFG)" == "agistudio - Win32 Debug"
# Begin Custom Build - Moc'ing logedit.h...
InputPath=.\logedit.h
"moc_logedit.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
%QTDIR%\bin\moc.exe logedit.h -o moc_logedit.cpp
# End Custom Build
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\logic.h
# End Source File
# Begin Source File
SOURCE=.\menu.h
!IF "$(CFG)" == "agistudio - Win32 Release"
# Begin Custom Build - Moc'ing menu.h...
InputPath=.\menu.h
"moc_menu.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
%QTDIR%\bin\moc.exe menu.h -o moc_menu.cpp
# End Custom Build
!ELSEIF "$(CFG)" == "agistudio - Win32 Debug"
# Begin Custom Build - Moc'ing menu.h...
InputPath=.\menu.h
"moc_menu.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
%QTDIR%\bin\moc.exe menu.h -o moc_menu.cpp
# End Custom Build
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\object.h
# End Source File
# Begin Source File
SOURCE=.\objedit.h
!IF "$(CFG)" == "agistudio - Win32 Release"
# Begin Custom Build - Moc'ing objedit.h...
InputPath=.\objedit.h
"moc_objedit.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
%QTDIR%\bin\moc.exe objedit.h -o moc_objedit.cpp
# End Custom Build
!ELSEIF "$(CFG)" == "agistudio - Win32 Debug"
# Begin Custom Build - Moc'ing objedit.h...
InputPath=.\objedit.h
"moc_objedit.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
%QTDIR%\bin\moc.exe objedit.h -o moc_objedit.cpp
# End Custom Build
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\options.h
!IF "$(CFG)" == "agistudio - Win32 Release"
# Begin Custom Build - Moc'ing options.h...
InputPath=.\options.h
"moc_options.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
%QTDIR%\bin\moc.exe options.h -o moc_options.cpp
# End Custom Build
!ELSEIF "$(CFG)" == "agistudio - Win32 Debug"
# Begin Custom Build - Moc'ing options.h...
InputPath=.\options.h
"moc_options.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
%QTDIR%\bin\moc.exe options.h -o moc_options.cpp
# End Custom Build
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\picedit.h
!IF "$(CFG)" == "agistudio - Win32 Release"
# Begin Custom Build - Moc'ing picedit.h...
InputPath=.\picedit.h
"moc_picedit.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
%QTDIR%\bin\moc.exe picedit.h -o moc_picedit.cpp
# End Custom Build
!ELSEIF "$(CFG)" == "agistudio - Win32 Debug"
# Begin Custom Build - Moc'ing picedit.h...
InputPath=.\picedit.h
"moc_picedit.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
%QTDIR%\bin\moc.exe picedit.h -o moc_picedit.cpp
# End Custom Build
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\picture.h
# End Source File
# Begin Source File
SOURCE=.\preview.h
!IF "$(CFG)" == "agistudio - Win32 Release"
# Begin Custom Build - Moc'ing preview.h...
InputPath=.\preview.h
"moc_preview.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
%QTDIR%\bin\moc.exe preview.h -o moc_preview.cpp
# End Custom Build
!ELSEIF "$(CFG)" == "agistudio - Win32 Debug"
# Begin Custom Build - Moc'ing preview.h...
InputPath=.\preview.h
"moc_preview.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
%QTDIR%\bin\moc.exe preview.h -o moc_preview.cpp
# End Custom Build
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\resources.h
!IF "$(CFG)" == "agistudio - Win32 Release"
# Begin Custom Build - Moc'ing resources.h...
InputPath=.\resources.h
"moc_resources.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
%QTDIR%\bin\moc.exe resources.h -o moc_resources.cpp
# End Custom Build
!ELSEIF "$(CFG)" == "agistudio - Win32 Debug"
# Begin Custom Build - Moc'ing resources.h...
InputPath=.\resources.h
"moc_resources.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
%QTDIR%\bin\moc.exe resources.h -o moc_resources.cpp
# End Custom Build
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\roomgen.h
!IF "$(CFG)" == "agistudio - Win32 Release"
# Begin Custom Build - Moc'ing roomgen.h...
InputPath=.\roomgen.h
"moc_roomgen.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
%QTDIR%\bin\moc.exe roomgen.h -o moc_roomgen.cpp
# End Custom Build
!ELSEIF "$(CFG)" == "agistudio - Win32 Debug"
# Begin Custom Build - Moc'ing roomgen.h...
InputPath=.\roomgen.h
"moc_roomgen.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
%QTDIR%\bin\moc.exe roomgen.h -o moc_roomgen.cpp
# End Custom Build
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\util.h
# End Source File
# Begin Source File
SOURCE=.\view.h
# End Source File
# Begin Source File
SOURCE=.\viewedit.h
!IF "$(CFG)" == "agistudio - Win32 Release"
# Begin Custom Build - Moc'ing viewedit.h...
InputPath=.\viewedit.h
"moc_viewedit.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
%QTDIR%\bin\moc.exe viewedit.h -o moc_viewedit.cpp
# End Custom Build
!ELSEIF "$(CFG)" == "agistudio - Win32 Debug"
# Begin Custom Build - Moc'ing viewedit.h...
InputPath=.\viewedit.h
"moc_viewedit.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
%QTDIR%\bin\moc.exe viewedit.h -o moc_viewedit.cpp
# End Custom Build
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\words.h
# End Source File
# Begin Source File
SOURCE=.\wordsedit.h
!IF "$(CFG)" == "agistudio - Win32 Release"
# Begin Custom Build - Moc'ing wordsedit.h...
InputPath=.\wordsedit.h
"moc_wordsedit.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
%QTDIR%\bin\moc.exe wordsedit.h -o moc_wordsedit.cpp
# End Custom Build
!ELSEIF "$(CFG)" == "agistudio - Win32 Debug"
# Begin Custom Build - Moc'ing wordsedit.h...
InputPath=.\wordsedit.h
"moc_wordsedit.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
%QTDIR%\bin\moc.exe wordsedit.h -o moc_wordsedit.cpp
# End Custom Build
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\wutil.h
!IF "$(CFG)" == "agistudio - Win32 Release"
# Begin Custom Build - Moc'ing wutil.h...
InputPath=.\wutil.h
"moc_wutil.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
%QTDIR%\bin\moc.exe wutil.h -o moc_wutil.cpp
# End Custom Build
!ELSEIF "$(CFG)" == "agistudio - Win32 Debug"
# Begin Custom Build - Moc'ing wutil.h...
InputPath=.\wutil.h
"moc_wutil.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
%QTDIR%\bin\moc.exe wutil.h -o moc_wutil.cpp
# End Custom Build
!ENDIF
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# Begin Source File
SOURCE=.\agistudio.rc
# End Source File
# Begin Source File
SOURCE=.\icon1.ico
# End Source File
# End Group
# Begin Group "Interfaces"
# PROP Default_Filter "ui"
# End Group
# Begin Source File
SOURCE=.\license.txt
# End Source File
# End Target
# End Project

29
src/agistudio.dsw Normal file
View File

@@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "agistudio"=".\agistudio.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

114
src/agistudio.kdevelop Normal file
View File

@@ -0,0 +1,114 @@
<!DOCTYPE kdevelop>
<kdevelop>
<general>
<author>Jarno Elonen</author>
<email>elonen@iki.fi</email>
<version>$VERSION$</version>
<projectmanagement>KDevTrollProject</projectmanagement>
<primarylanguage>C++</primarylanguage>
<keywords>
<keyword>Qt</keyword>
</keywords>
<projectdirectory>.</projectdirectory>
<absoluteprojectpath>false</absoluteprojectpath>
<description>QT AGI Studio is a program which allows you to view, create and edit AGI games. AGI (Adventure Game Interpreter) is the adventure game engine used by Sierra On-Line(tm) to create some of their early games.</description>
<ignoreparts>
<part>KDevClearCase</part>
<part>KDevDoxygen</part>
<part>KDevdistpart</part>
<part>KDevPerforce</part>
<part>KDevVisualBoyAdvance</part>
</ignoreparts>
</general>
<kdevfileview>
<groups>
<group pattern="*.cpp;*.cxx;*.h" name="Sources" />
<group pattern="*.ui" name="User Interface" />
<group pattern="*.png" name="Icons" />
<group pattern="*" name="Others" />
</groups>
<tree>
<hidenonprojectfiles>false</hidenonprojectfiles>
<hidepatterns>*.o,*.lo,CVS</hidepatterns>
</tree>
</kdevfileview>
<kdevdoctreeview>
<ignoretocs>
<toc>gtk</toc>
<toc>gnustep</toc>
<toc>python</toc>
<toc>php</toc>
<toc>perl</toc>
</ignoretocs>
<projectdoc>
<userdocDir>../help/</userdocDir>
<apidocDir/>
</projectdoc>
</kdevdoctreeview>
<kdevdebugger>
<general>
<dbgshell/>
<programargs/>
<gdbpath/>
<breakonloadinglibs>true</breakonloadinglibs>
<separatetty>false</separatetty>
<floatingtoolbar>true</floatingtoolbar>
<runappinappdirectory>true</runappinappdirectory>
</general>
<display>
<staticmembers>false</staticmembers>
<demanglenames>true</demanglenames>
</display>
</kdevdebugger>
<kdevfilecreate>
<filetypes/>
<useglobaltypes>
<type ext="ui" />
<type ext="cpp" />
<type ext="h" />
</useglobaltypes>
</kdevfilecreate>
<kdevtrollproject>
<general>
<activedir></activedir>
</general>
<make>
<abortonerror>false</abortonerror>
<numberofjobs>1</numberofjobs>
<dontact>false</dontact>
<makebin/>
<envvars/>
</make>
<run>
<mainprogram>agistudio</mainprogram>
<programargs/>
<terminal>false</terminal>
<envvars/>
</run>
</kdevtrollproject>
<cppsupportpart>
<codecompletion/>
<filetemplates>
<choosefiles>false</choosefiles>
<interfaceURL/>
<implementationURL/>
<interfacesuffix>.h</interfacesuffix>
<implementationsuffix>.cpp</implementationsuffix>
<lowercasefilenames>true</lowercasefilenames>
</filetemplates>
</cppsupportpart>
<kdevclassview>
<folderhierarchy>true</folderhierarchy>
<depthoffolders>2</depthoffolders>
</kdevclassview>
<kdevcvs>
<cvsoptions>-f</cvsoptions>
<commitoptions/>
<updateoptions>-dP</updateoptions>
<addoptions/>
<removeoptions>-f</removeoptions>
<diffoptions>-u3 -p</diffoptions>
<logoptions/>
<rshoptions/>
</kdevcvs>
</kdevelop>

63
src/agistudio.pro Normal file
View File

@@ -0,0 +1,63 @@
TEMPLATE = app
CONFIG = qt warn_on release thread
#CONFIG = qt warn_on debug thread
# DEFINES += QT_DLL QT_THREAD_SUPPORT # win32
QMAKE_CXXFLAGS += -Wno-unused-result
HEADERS = agicommands.h \
dir.h \
game.h \
global.h \
helpwindow.h \
linklist.h \
logedit.h \
logic.h \
menu.h \
midi.h \
object.h \
objedit.h \
options.h \
picedit.h \
picture.h \
preview.h \
resources.h \
roomgen.h \
util.h \
view.h \
viewedit.h \
words.h \
wordsedit.h \
wutil.h \
bmp2agipic.h
SOURCES = agicommands.cpp \
agiplay.cpp \
bpicture.cpp \
dir.cpp \
game.cpp \
helpwindow.cpp \
linklist.cpp \
logcompile.cpp \
logdecode.cpp \
logedit.cpp \
logic.cpp \
main.cpp \
menu.cpp \
midi.cpp \
object.cpp \
objedit.cpp \
options.cpp \
picedit.cpp \
picture.cpp \
preview.cpp \
resources.cpp \
roomgen.cpp \
util.cpp \
view.cpp \
viewedit.cpp \
words.cpp \
wordsedit.cpp \
wutil.cpp \
bmp2agipic.cpp
TARGET = agistudio
#The following line was inserted by qt3to4
QT += qt3support

72
src/agistudio.rc Normal file
View File

@@ -0,0 +1,72 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_ICON1 ICON DISCARDABLE "icon1.ico"
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

40
src/app_icon.xpm Normal file
View File

@@ -0,0 +1,40 @@
/* XPM */
static const char * app_icon[] = {
"32 32 5 1",
" c None",
". c #000000",
"+ c #FF5050",
"@ c #A00000",
"# c #0000A0",
" ",
" ",
" ........ ",
" ........ ",
" ................ ",
" ................ ",
" ........++++ ",
" ........++++ ",
" ....++++@@@@ ",
" ....++++@@@@ ",
" ....++++++++++++ ",
" ....++++++++++++ ",
" ....++++++++ ",
" ....++++++++ ",
" ....++++++++ ",
" ....++++++++ ",
" ....++++++++ ",
" ....++++++++ ",
" ++++ ",
" ++++ ",
" #### ",
" #### ",
" ############ ",
" ############ ",
" ############ ",
" ############ ",
" ################ ",
" ################ ",
" #################### ",
" #################### ",
" ########################+++ ",
" ########################+++ "};

27
src/back.xpm Normal file
View File

@@ -0,0 +1,27 @@
/* XPM */
static const char *back[] = {
/* columns rows colors chars-per-pixel */
"16 16 5 1",
" c black",
". c #808080808080",
"X c #C0C0C0C0C0C0",
"o c gray100",
"O c None",
/* pixels */
"OOOOOOOOOOOOOOOO",
"OOOOOOO OOOOOOOO",
"OOOOOO OOOOOOOO",
"OOOOO o OOOOOOOO",
"OOOO oo O",
"OOO ooXooooooo O",
"OO ooXXXXXXXXX O",
"OOO oXXXXXXXXX O",
"OOO. oX O",
"OOOO. o .......O",
"OOOOO. .OOOOOOO",
"OOOOOO. .OOOOOOO",
"OOOOOOO..OOOOOOO",
"OOOOOOOO.OOOOOOO",
"OOOOOOOOOOOOOOOO",
"OOOOOOOOOOOOOOOO"
};

413
src/bmp2agipic.cpp Normal file
View File

@@ -0,0 +1,413 @@
/*
* Bitmap to (Sierra) AGI picture resource converter
* Copyright (C) 2012 Jarno Elonen
*
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include "bmp2agipic.h"
#include <QColor>
#include <cmath>
#include <queue>
#include <vector>
#include <cstdio>
#include <cassert>
static const int AGI_WIDTH = 160;
static const int AGI_HEIGHT = 168;
static const int N_COLORS = 16;
static const unsigned char COLOR_NONE = 255;
const QColor ega[] = {
QColor(0x00, 0x00, 0x00), // black
QColor(0x00, 0x00, 0xA0), // blue
QColor(0x00, 0xA0, 0x00), // green
QColor(0x00, 0xA0, 0xA0), // cyan
QColor(0xA0, 0x00, 0x00), // red
QColor(0xA0, 0x00, 0xA0), // magenta
QColor(0xA0, 0x50, 0x00), // brown
QColor(0xA0, 0xA0, 0xA0), // light grey
QColor(0x50, 0x50, 0x50), // dark grey
QColor(0x50, 0x50, 0xFF), // light blue
QColor(0x50, 0xFF, 0x50), // light green
QColor(0x50, 0xFF, 0xFF), // light cyan
QColor(0xFF, 0x50, 0x50), // light red
QColor(0xFF, 0x50, 0xFF), // light magenta
QColor(0xFF, 0xFF, 0x50), // yellow
QColor(0xFF, 0xFF, 0xFF) // white
};
typedef unsigned char AGIPic[AGI_WIDTH][AGI_HEIGHT];
struct Coord {
Coord( int _x, int _y ) : x(_x), y(_y) {}
int x, y;
};
struct CoordColor {
CoordColor( int _x, int _y, unsigned char _c ) : x(_x), y(_y), c(_c) {}
int x, y;
unsigned char c;
};
// Quantize given image to EGA palette and reshape to AGI native AGI_WIDTHxAGI_HEIGHT
void QuantizeAGI( const QImage& img, AGIPic& out )
{
#define SQUARE(x) ((x)*(x))
assert(img.width() == AGI_WIDTH || img.width() == AGI_WIDTH*2 );
assert(img.height() >= AGI_HEIGHT );
int xstep = (img.width() == AGI_WIDTH) ? 1 : 2;
for ( int y=0; y<AGI_HEIGHT; ++y )
{
for ( int x=0; x<img.width(); x+=xstep )
{
float selErr = -1.f;
unsigned char sel = 0;
for ( int c=0; c<N_COLORS; ++c )
{
QColor pix( img.pixel(x,y) );
float err = sqrtf(
SQUARE(ega[c].redF() - pix.redF()) +
SQUARE(ega[c].greenF() - pix.greenF()) +
SQUARE(ega[c].blueF() - pix.blueF()));
if ( selErr < 0.f || err < selErr )
{
sel = c;
selErr =err;
}
}
out[x/xstep][y] = sel;
}
}
}
unsigned char& agiPix( AGIPic& pic, int x, int y )
{
static unsigned char dummy = COLOR_NONE;
assert(dummy == COLOR_NONE); // not been accidentally overwritten...
if ( x<0 || x>=AGI_WIDTH || y<0 || y>=AGI_HEIGHT )
return dummy;
else
return pic[x][y];
}
// Returns true if neighborhood is solid, suitable for floodfill
bool isOnFloodFillArea( AGIPic& pic, int x, int y )
{
if ( agiPix(pic, x,y) == COLOR_NONE )
return false;
for ( int dx=-1; dx<=1; ++dx )
for ( int dy=-1; dy<=1; ++dy )
if ( agiPix(pic, x,y) != agiPix(pic, x+dx,y+dy))
return false;
return true;
}
bool has4NeighborOfColor( AGIPic& pic, int x, int y, unsigned char c )
{
return \
(x<AGI_WIDTH-1 && agiPix(pic,x+1,y+0) == c) ||
(x>0 && agiPix(pic,x-1,y+0) == c) ||
(y<AGI_HEIGHT-1 && agiPix(pic,x+0,y+1) == c) ||
(y>0 && agiPix(pic,x+0,y-1) == c);
}
// Trace how long a line continues to given direction (excluding starting pixel)
int traceToDir( AGIPic& pic, int x, int y, int dx, int dy, unsigned char c, int max )
{
assert(c != COLOR_NONE); // could cause infinite trace
int cnt = -1;
do
{
cnt++;
if ( cnt >= max )
break;
x+=dx;
y+=dy;
} while ( agiPix(pic,x, y) == c );
return cnt;
}
int count8NeighborOfColor( AGIPic& pic, int x, int y, unsigned char c )
{
int res = 0;
for ( int dx=-1; dx<=1; ++dx )
for ( int dy=-1; dy<=1; ++dy )
if ( dx!=0 || dy!=0 )
if ( agiPix(pic,x+dx,y+dy) == c )
res++;
return res;
}
// Flood fill area with color COLOR_NONE, but
// leave border pixels of previous COLOR_NONE areas
// untouched so that we'll get proper fill borders later.
void floodFillEmpty( AGIPic& pic, int x, int y )
{
std::queue<Coord> q;
q.push(Coord(x,y));
const unsigned char visited = COLOR_NONE-1;
const unsigned char src_color = pic[x][y];
assert( src_color != COLOR_NONE );
assert( src_color != visited );
while ( !q.empty())
{
Coord c = q.front();
q.pop();
if ( agiPix(pic, c.x, c.y) == src_color &&
!has4NeighborOfColor(pic,c.x,c.y, COLOR_NONE ))
{
agiPix(pic, c.x, c.y) = visited;
q.push(Coord(c.x+1, c.y+0));
q.push(Coord(c.x-1, c.y+0));
q.push(Coord(c.x+0, c.y+1));
q.push(Coord(c.x+0, c.y-1));
}
}
for (int y=0; y<AGI_HEIGHT; ++y )
for (int x=0; x<AGI_WIDTH; ++x )
if ( agiPix(pic,x,y) == visited )
agiPix(pic,x,y) = COLOR_NONE;
}
int findBestLineStartFromArea( AGIPic& pic, int x0, int y0, int w, int h, int color, std::vector<Coord>& singlePoints, Coord& minCoord )
{
// Find pixel with the least neighbors of color i
// (i.e. most probable end of line)
int minCount = 0xFF;
for (int y=y0; y<y0+h; ++y )
for (int x=x0; x<x0+w; ++x )
{
if ( agiPix(pic,x,y) == color )
{
int cnt = count8NeighborOfColor( pic,x,y, agiPix(pic,x,y) );
if ( cnt == 0 ) // lonely pixel, handle immediately
{
singlePoints.push_back(Coord(x,y));
agiPix(pic,x,y) = COLOR_NONE;
}
else if ( cnt < minCount ) // line
{
minCount = cnt;
minCoord.x = x;
minCoord.y = y;
}
}
}
return minCount;
}
void replaceLines( AGIPic& pic, QByteArray* res, bool isPri )
{
// Handle one color at a time
for (int color=0; color<N_COLORS; ++color )
{
// Check that there's at least one pixel of color i left
for (int y=0; y<AGI_HEIGHT; ++y )
for (int x=0; x<AGI_WIDTH; ++x )
if ( agiPix(pic,x,y) == color )
goto found;
continue;
found:
*res += char( isPri ? 0xF2 : 0xF0 ); // Change color command
*res += char( color ); // Color index
std::vector<Coord> singlePoints;
while (true) // loop until no pixels of color i are found
{
Coord minCoord(-1,-1);
int minCount = findBestLineStartFromArea( pic, 0,0, AGI_WIDTH,AGI_HEIGHT, color, singlePoints, minCoord );
if ( minCount == 0xFF ) // No more lines found
break;
newTrace:
// Start tracing the line
int x=minCoord.x, y=minCoord.y;
assert( agiPix(pic,x,y) == color );
*res += char( 0xF7 ); // Relative line command
*res += char( x ); // Starting x
*res += char( y ); // Starting y
agiPix(pic,x,y) = COLOR_NONE;
// Trace a line
while (true)
{
// Find out direction into which the line continues the longest
int max=0, maxdx=0xFF,maxdy=0xFF;
for ( int dx=-1; dx<=1; ++dx )
for ( int dy=-1; dy<=1; ++dy )
if ( dx != 0 || dy != 0 )
{
int len = traceToDir( pic, x,y, dx,dy, color, AGI_WIDTH );
if ( len > max )
{
max = len;
maxdx = dx;
maxdy = dy;
}
}
if ( max==0 ) // Nowhere to go, end the trace
{
// Just for aesthetic reasons, try to start the next
// line nearby the end of the last one
minCount = findBestLineStartFromArea( pic, x-5,y-5, 10,10, color, singlePoints, minCoord );
if ( minCount == 0xFF )
break; // Not found, do a full pic scan
else
goto newTrace; // New line in the neighborhood, start from there
}
if ( max>6 ) // Clamp to maximum length of relative line
max=6;
int stepx = maxdx*max;
int stepy = maxdy*max;
assert(abs(stepx) <= 7);
assert(abs(stepy) <= 7);
// Write out the relative line stepping byte
unsigned char chr =
(((stepx<0)?1:0) << 7) | // x sign
(abs(stepx) << 4) | // Xdisp
(((stepy<0)?1:0) << 3) | // y sign
(abs(stepy) << 0); // Ydisp
assert((chr&0xF0) != 0xF0); // Must not be mistaken for a draw command
*res += char(chr);
// Clear the line
while (max>=0)
{
agiPix(pic,x+maxdx*max,y+maxdy*max) = COLOR_NONE;
--max;
}
// Move pointer to the new end
x += stepx;
y += stepy;
}
}
// When all continuous lines are drawn,
// write out single points as a brush/plot/pen operation
if ( singlePoints.size()>0 )
{
*res += char( 0xFA ); // Pen command
for ( int i=0; i<(int)singlePoints.size(); ++i )
{
assert( (unsigned char)singlePoints[i].x < 0xF0);
assert( (unsigned char)singlePoints[i].y < 0xF0);
*res += char( singlePoints[i].x );
*res += char( singlePoints[i].y );
}
}
}
}
// Convert either a visual or a priority image and write to res
void oneChannelToAGIPicture( const QImage& chan, QByteArray* res, bool isPri )
{
unsigned char pic[AGI_WIDTH][AGI_HEIGHT];
QuantizeAGI( chan, pic );
// We're doing one channel at a time, disable the other one first
*res += char( isPri ? 0xF1 : 0xF3 );
// Clear the default color, no sense in filling/drawing with it:
unsigned default_color = isPri ? 4 : 15; // 4=red for pri, 15=white for visual
for (int y=0; y<AGI_HEIGHT; ++y )
for (int x=0; x<AGI_WIDTH; ++x )
if ( agiPix(pic,x,y) == default_color )
agiPix(pic,x,y) = COLOR_NONE;
// Record flood fill areas and empty them
// (color by color in reverse order to favor black outlines)
std::vector<CoordColor> floodFills;
for ( int c=N_COLORS-1; c>=0; --c )
for (int y=0; y<AGI_HEIGHT; ++y )
for (int x=0; x<AGI_WIDTH; ++x )
if ( agiPix(pic,x,y) == c && isOnFloodFillArea(pic,x,y) )
{
floodFills.push_back(CoordColor(x,y, agiPix(pic,x,y)));
floodFillEmpty(pic,x,y);
}
// Replace lines and single pixels with commands
replaceLines( pic, res, isPri );
// Write out flood fills
unsigned char curColor = COLOR_NONE;
for ( int i=0; i<(int)floodFills.size(); ++i)
{
CoordColor c = floodFills[i];
assert( c.c != default_color ); // we shouldn't need to fill with default color
floodFills.erase( floodFills.begin()+i);
i--;
if ( curColor != c.c )
{
curColor = c.c;
*res += char( isPri ? 0xF2 : 0xF0 ); // Change color command
*res += char( c.c ); // Color index
*res += char( 0xF8 ); // Flood fill command
}
assert( curColor != COLOR_NONE ); // i.e: flood fill command written
*res += char( c.x );
*res += char( c.y );
}
assert( floodFills.empty());
}
// Converts bitmaps (pic and pri) into an AGI "picture" resrouce.
// Returns NULL if success, or error message otherwise.
const char* bitmapToAGIPicture( const QImage& pic, const QImage& pri, QByteArray* res )
{
// Check given images & convert to EGA palette arrays
if ( (pic.width() != AGI_WIDTH*2 && pic.width() != AGI_WIDTH) || pic.height() < AGI_HEIGHT )
return("Picture bitmap size must be 160x168 or 320x168.");
if ( !pri.isNull())
if ( (pri.width() != AGI_WIDTH*2 && pri.width() != AGI_WIDTH) || pri.height() < AGI_HEIGHT )
return("Priority bitmap size must be 160x168 or 320x168.");
// Set brush once at the beginning
*res += char( 0xF9 ); // Change pen size & style
*res += char( 0x00 ); // solid single pixel
oneChannelToAGIPicture( pic, res, false);
if ( !pri.isNull())
oneChannelToAGIPicture( pri, res, true);
*res += char( 0xFF ); // eof marker
return NULL;
}

33
src/bmp2agipic.h Normal file
View File

@@ -0,0 +1,33 @@
/*
* Bitmap to (Sierra) AGI picture resource converter
* Copyright (C) 2012 Jarno Elonen
*
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef bmp2agipic_h
#define bmp2agipic_h
#include <QImage>
#include <QByteArray>
// Converts bitmaps (pic and pri) into an AGI "picture" resource.
// Returns NULL if success, or error message otherwise.
// Pri image may be null (QImage.isNull().
const char* bitmapToAGIPicture( const QImage& pic, const QImage& pri, QByteArray* res );
#endif

545
src/bpicture.cpp Normal file
View File

@@ -0,0 +1,545 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
* Almost all of the picture processing code is taken from showpic.c
* by Lance Ewing <lance.e@ihug.co.nz>
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include "game.h"
#include "menu.h"
#include "picture.h"
#include <stdio.h>
#include <sys/types.h>
#ifndef _WIN32
#include <unistd.h>
#endif
#include <sys/stat.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
BPicture *ppicture;
//********************************************
//"bytemap" picture for preview - it is not going to be edited,
//so there is no need for the linked list and other things from the Picture class
BPicture::BPicture()
{
picture = (byte **)malloc(MAX_H*sizeof(byte *));
priority = (byte **)malloc(MAX_H*sizeof(byte *));
for(int i=0;i<MAX_H;i++){
picture[i] = (byte *)malloc(MAX_W);
priority[i] = (byte *)malloc(MAX_W);
}
}
//****************************************************
void BPicture::qstore(byte q)
{
if (spos+1==rpos || (spos+1==QUMAX && !rpos)) {
//nosound();
return;
}
buf[spos] = q;
spos++;
if (spos==QUMAX) spos = 0; /* loop back */
}
//********************************************
byte BPicture::qretrieve()
{
if (rpos==QUMAX) rpos=0; /* loop back */
if (rpos==spos) {
return EMPTY;
}
rpos++;
return buf[rpos-1];
}
/**************************************************************************
** picPSet
**
** Draws a pixel in the picture screen.
**************************************************************************/
void BPicture::picPSet(word x, word y)
{
word vx, vy;
vx = (x << 1);
vy = y;
if (vx > 319) return;
if (vy > 199) return;
picture[vy][vx] = picColour;
picture[vy][vx+1] = picColour;
}
/**************************************************************************
** priPSet
**
** Draws a pixel in the priority screen.
**************************************************************************/
void BPicture::priPSet(word x, word y)
{
word vx, vy;
vx = (x << 1);
vy = y;
if (vx > 319) return;
if (vy > 199) return;
priority[vy][vx] = priColour;
priority[vy][vx+1] = priColour;
}
/**************************************************************************
** pset
**
** Draws a pixel in each screen depending on whether drawing in that
** screen is enabled or not.
**************************************************************************/
void BPicture::pset(word x, word y)
{
if (picDrawEnabled) picPSet(x, y);
if (priDrawEnabled) priPSet(x, y);
}
/**************************************************************************
** picGetPixel
**
** Get colour at x,y on the picture page.
**************************************************************************/
byte BPicture::picGetPixel(word x, word y)
{
word vx, vy;
vx = (x << 1);
vy = y;
if (vx > 319) return(4);
if (vy > 199) return(4);
return (picture[vy][vx]);
}
/**************************************************************************
** priGetPixel
**
** Get colour at x,y on the priority page.
**************************************************************************/
byte BPicture::priGetPixel(word x, word y)
{
word vx, vy;
vx = (x << 1);
vy = y;
if (vx > 319) return(4);
if (vy > 199) return(4);
return (priority[vy][vx]);
}
/**************************************************************************
** round
**
** Rounds a float to the closest int. Takes into actions which direction
** the current line is being drawn when it has a 50:50 decision about
** where to put a pixel.
**************************************************************************/
int BPicture::round(float aNumber, float dirn)
{
if (dirn < 0)
return ((aNumber - floor(aNumber) <= 0.501)? (int)floor(aNumber) : (int)ceil(aNumber));
return ((aNumber - floor(aNumber) < 0.499)? (int)floor(aNumber) : (int)ceil(aNumber));
}
/**************************************************************************
** drawline
**
** Draws an AGI line.
**************************************************************************/
void BPicture::drawline(word x1, word y1, word x2, word y2)
{
int height, width;
float x, y, addX, addY;
height = (y2 - y1);
width = (x2 - x1);
addX = (height==0?height:(float)width/abs(height));
addY = (width==0?width:(float)height/abs(width));
if (abs(width) > abs(height)) {
y = y1;
addX = (width == 0? 0 : (width/abs(width)));
for (x=x1; x!=x2; x+=addX) {
pset(round(x, addX), round(y, addY));
y+=addY;
}
pset(x2,y2);
}
else {
x = x1;
addY = (height == 0? 0 : (height/abs(height)));
for (y=y1; y!=y2; y+=addY) {
pset(round(x, addX), round(y, addY));
x+=addX;
}
pset(x2,y2);
}
}
/**************************************************************************
** okToFill
**************************************************************************/
bool BPicture::okToFill(byte x, byte y)
{
if (!picDrawEnabled && !priDrawEnabled) return false;
if (picColour == 15) return false;
if (!priDrawEnabled) return (picGetPixel(x, y) == 15);
if (priDrawEnabled && !picDrawEnabled) return (priGetPixel(x, y) == 4);
return (picGetPixel(x, y) == 15);
}
/**************************************************************************
** agiFill
**************************************************************************/
void BPicture::agiFill(word x, word y)
{
byte x1, y1;
rpos = spos = 0;
qstore(x);
qstore(y);
// printf("fill %d %d\n",x,y);
for (;;) {
x1 = qretrieve();
y1 = qretrieve();
// printf("x1=%d y1=%d\n");
if ((x1 == EMPTY) || (y1 == EMPTY))
break;
else {
if (okToFill(x1,y1)) {
pset(x1, y1);
if (okToFill(x1, y1-1) && (y1!=0)) {
qstore(x1);
qstore(y1-1);
}
if (okToFill(x1-1, y1) && (x1!=0)) {
qstore(x1-1);
qstore(y1);
}
if (okToFill(x1+1, y1) && (x1!=159)) {
qstore(x1+1);
qstore(y1);
}
if (okToFill(x1, y1+1) && (y1!=167)) {
qstore(x1);
qstore(y1+1);
}
}
}
}
}
/**************************************************************************
** xCorner
**
** Draws an xCorner (drawing action 0xF5)
**************************************************************************/
void BPicture::xCorner(byte **data)
{
byte x1, x2, y1, y2;
x1 = *((*data)++);
y1 = *((*data)++);
pset(x1,y1);
for (;;) {
x2 = *((*data)++);
if (x2 >= 0xF0) break;
drawline(x1, y1, x2, y1);
x1 = x2;
y2 = *((*data)++);
if (y2 >= 0xF0) break;
drawline(x1, y1, x1, y2);
y1 = y2;
}
(*data)--;
}
/**************************************************************************
** yCorner
**
** Draws an yCorner (drawing action 0xF4)
**************************************************************************/
void BPicture::yCorner(byte **data)
{
byte x1, x2, y1, y2;
x1 = *((*data)++);
y1 = *((*data)++);
pset(x1, y1);
for (;;) {
y2 = *((*data)++);
if (y2 >= 0xF0) break;
drawline(x1, y1, x1, y2);
y1 = y2;
x2 = *((*data)++);
if (x2 >= 0xF0) break;
drawline(x1, y1, x2, y1);
x1 = x2;
}
(*data)--;
}
/**************************************************************************
** relativeDraw
**
** Draws short lines relative to last position. (drawing action 0xF7)
**************************************************************************/
void BPicture::relativeDraw(byte **data)
{
byte x1, y1, disp;
char dx, dy;
x1 = *((*data)++);
y1 = *((*data)++);
pset(x1, y1);
for (;;) {
disp = *((*data)++);
if (disp >= 0xF0) break;
dx = ((disp & 0xF0) >> 4) & 0x0F;
dy = (disp & 0x0F);
if (dx & 0x08) dx = (-1)*(dx & 0x07);
if (dy & 0x08) dy = (-1)*(dy & 0x07);
drawline(x1, y1, x1 + dx, y1 + dy);
x1 += dx;
y1 += dy;
}
(*data)--;
}
/**************************************************************************
** fill
**
** Agi flood fill. (drawing action 0xF8)
**************************************************************************/
void BPicture::fill(byte **data)
{
byte x1, y1;
for (;;) {
if ((x1 = *((*data)++)) >= 0xF0) break;
if ((y1 = *((*data)++)) >= 0xF0) break;
agiFill(x1, y1);
}
(*data)--;
}
/**************************************************************************
** absoluteLine
**
** Draws long lines to actual locations (cf. relative) (drawing action 0xF6)
**************************************************************************/
void BPicture::absoluteLine(byte **data)
{
byte x1, y1, x2, y2;
x1 = *((*data)++);
y1 = *((*data)++);
pset(x1, y1);
for (;;) {
if ((x2 = *((*data)++)) >= 0xF0) break;
if ((y2 = *((*data)++)) >= 0xF0) break;
drawline(x1, y1, x2, y2);
x1 = x2;
y1 = y2;
}
(*data)--;
}
#define plotPatternPoint() \
if (patCode & 0x20) { \
if ((splatterMap[bitPos>>3] >> (7-(bitPos&7))) & 1) pset(x1, y1); \
bitPos++; \
if (bitPos == 0xff) bitPos=0; \
} else pset(x1, y1)
/**************************************************************************
** plotPattern
**
** Draws pixels, circles, squares, or splatter brush patterns depending
** on the pattern code.
**************************************************************************/
void BPicture::plotPattern(byte x, byte y)
{
static char circles[][15] = { /* agi circle bitmaps */
{0x80},
{0xfc},
{0x5f, 0xf4},
{0x66, 0xff, 0xf6, 0x60},
{0x23, 0xbf, 0xff, 0xff, 0xee, 0x20},
{0x31, 0xe7, 0x9e, 0xff, 0xff, 0xde, 0x79, 0xe3, 0x00},
{0x38, 0xf9, 0xf3, 0xef, 0xff, 0xff, 0xff, 0xfe, 0xf9, 0xf3, 0xe3, 0x80},
{0x18, 0x3c, 0x7e, 0x7e, 0x7e, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7e, 0x7e,
0x7e, 0x3c, 0x18}
};
static byte splatterMap[32] = { /* splatter brush bitmaps */
0x20, 0x94, 0x02, 0x24, 0x90, 0x82, 0xa4, 0xa2,
0x82, 0x09, 0x0a, 0x22, 0x12, 0x10, 0x42, 0x14,
0x91, 0x4a, 0x91, 0x11, 0x08, 0x12, 0x25, 0x10,
0x22, 0xa8, 0x14, 0x24, 0x00, 0x50, 0x24, 0x04
};
static byte splatterStart[128] = { /* starting bit position */
0x00, 0x18, 0x30, 0xc4, 0xdc, 0x65, 0xeb, 0x48,
0x60, 0xbd, 0x89, 0x05, 0x0a, 0xf4, 0x7d, 0x7d,
0x85, 0xb0, 0x8e, 0x95, 0x1f, 0x22, 0x0d, 0xdf,
0x2a, 0x78, 0xd5, 0x73, 0x1c, 0xb4, 0x40, 0xa1,
0xb9, 0x3c, 0xca, 0x58, 0x92, 0x34, 0xcc, 0xce,
0xd7, 0x42, 0x90, 0x0f, 0x8b, 0x7f, 0x32, 0xed,
0x5c, 0x9d, 0xc8, 0x99, 0xad, 0x4e, 0x56, 0xa6,
0xf7, 0x68, 0xb7, 0x25, 0x82, 0x37, 0x3a, 0x51,
0x69, 0x26, 0x38, 0x52, 0x9e, 0x9a, 0x4f, 0xa7,
0x43, 0x10, 0x80, 0xee, 0x3d, 0x59, 0x35, 0xcf,
0x79, 0x74, 0xb5, 0xa2, 0xb1, 0x96, 0x23, 0xe0,
0xbe, 0x05, 0xf5, 0x6e, 0x19, 0xc5, 0x66, 0x49,
0xf0, 0xd1, 0x54, 0xa9, 0x70, 0x4b, 0xa4, 0xe2,
0xe6, 0xe5, 0xab, 0xe4, 0xd2, 0xaa, 0x4c, 0xe3,
0x06, 0x6f, 0xc6, 0x4a, 0xa4, 0x75, 0x97, 0xe1
};
int circlePos = 0;
byte x1, y1, penSize, bitPos = splatterStart[patNum];
penSize = (patCode&7);
if (x<((penSize/2)+1)) x=((penSize/2)+1);
else if (x>160-((penSize/2)+1)) x=160-((penSize/2)+1);
if (y<penSize) y = penSize;
else if (y>=168-penSize) y=167-penSize;
for (y1=y-penSize; y1<=y+penSize; y1++) {
for (x1=x-((int)ceil((float)penSize/2)); x1<=x+((int)floor((float)penSize/2)); x1++) {
if (patCode & 0x10) { /* Square */
plotPatternPoint();
}
else { /* Circle */
if ((circles[patCode&7][circlePos>>3] >> (7-(circlePos&7)))&1) {
plotPatternPoint();
}
circlePos++;
}
}
}
}
/**************************************************************************
** plotBrush
**
** Plots points and various brush patterns.
**************************************************************************/
void BPicture::plotBrush(byte **data)
{
byte x1, y1;
for (;;) {
if (patCode & 0x20) {
if ((patNum = *((*data)++)) >= 0xF0) break;
patNum = (patNum >> 1 & 0x7f);
}
if ((x1 = *((*data)++)) >= 0xF0) break;
if ((y1 = *((*data)++)) >= 0xF0) break;
plotPattern(x1, y1);
}
(*data)--;
}
//****************************************************
void BPicture::show(byte *picdata,int picsize)
{
byte *data = picdata;
bool stillDrawing = true;
byte action;
for(int i=0;i<MAX_H;i++){
memset(picture[i],15,MAX_W);
memset(priority[i],4,MAX_W);
}
rpos = QUMAX;
spos = 0;
picDrawEnabled = false;
priDrawEnabled = false;
picColour = priColour = 0;
do {
action = *(data++);
switch (action) {
case 0xFF: stillDrawing = 0; break;
case 0xF0: picColour = *(data++);
picDrawEnabled = true;
break;
case 0xF1: picDrawEnabled = false; break;
case 0xF2: priColour = *(data++);
priDrawEnabled = true;
break;
case 0xF3: priDrawEnabled = false; break;
case 0xF4: yCorner(&data); break;
case 0xF5: xCorner(&data); break;
case 0xF6: absoluteLine(&data); break;
case 0xF7: relativeDraw(&data); break;
case 0xF8: fill(&data); break;
case 0xF9: patCode = *(data++); break;
case 0xFA: plotBrush(&data); break;
default: printf("Unknown picture code : %X\n", action); break;
}
}while((data < (data + picsize)) && stillDrawing);
}
//****************************************************

98
src/dir.cpp Normal file
View File

@@ -0,0 +1,98 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include "game.h"
#include "menu.h"
#include "dir.h"
#ifdef _WIN32
#include <io.h>
#else
#include <unistd.h>
#include <glob.h>
#endif
#include <QFileDialog>
//*********************************************************
void OpenGameDir( QWidget *parent, bool newgame )
{
QString title("Open game");
if(newgame)
title = "New game";
QString dir = QFileDialog::getExistingDirectory(parent, title);
if ( dir.isNull())
return;
//close the currently edited game
if(game->isOpen)
{
menu->close_game();
if(game->isOpen)return;
}
std::string name = dir.toLocal8Bit().data();
if(newgame)
{
int game_exists;
sprintf(tmp,"%s/*vol.?",name.c_str()); //check for an existing game
#ifdef _WIN32
struct _finddata_t c_file;
long hFile;
game_exists = !((hFile = _findfirst(tmp,&c_file)) == -1L);
if (game_exists) _findclose(hFile);
#else
glob_t globbuf;
glob(tmp, 0, NULL, &globbuf);
game_exists = globbuf.gl_pathc>0;
#endif
if (game_exists) {
sprintf(tmp,"There seems to be already an AGI game in %s !\nDo you want to erase it ?",name.c_str());
switch ( QMessageBox::warning( parent, "New game",
tmp,
"Yes",
"No",
"Cancel",
0, 2) ) {
case 0: // yes
break;
case 1: // no
return;
default: // cancel
return;
}
}
}
int err;
if(newgame)
{
if(menu->templ)
err = game->from_template(name);
else
err = game->newgame(name);
}
else
err = game->open(name);
if(!err)
menu->show_resources();
}

28
src/dir.h Normal file
View File

@@ -0,0 +1,28 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef DIR_H
#define DIR_H
#include <qwidget.h>
void OpenGameDir( QWidget *parent=0, bool newgame=false );
#endif

24
src/downarrow_x.xpm Normal file
View File

@@ -0,0 +1,24 @@
/* XPM */
static const char *downarrow_x[] = {
/* columns rows colors chars-per-pixel */
"16 16 2 1",
" c black",
". c None",
/* pixels */
"................",
"...... ......",
"...... ......",
"...... ......",
"...... ......",
"...... ......",
"...... ......",
" ",
" ",
". .",
".. ..",
"... ...",
".... ....",
"..... .....",
"...... ......",
"....... ......."
};

27
src/forward.xpm Normal file
View File

@@ -0,0 +1,27 @@
/* XPM */
static const char *forward[] = {
/* columns rows colors chars-per-pixel */
"16 16 5 1",
" c black",
". c #808080808080",
"X c #C0C0C0C0C0C0",
"o c gray100",
"O c None",
/* pixels */
"OOOOOOOOOOOOOOOO",
"OOOOOOOOOOOOOOOO",
"OOOOOOOOO OOOOOO",
"OOOOOOOOO OOOOO",
"OOOOOOOOO o OOOO",
"OO oo OOO",
"OO oooooooXoo OO",
"OO XXXXXXXXXoo O",
"OO XXXXXXXXXo OO",
"OO Xo .OO",
"OO....... o .OOO",
"OOOOOOOO. .OOOO",
"OOOOOOOO. .OOOOO",
"OOOOOOOO..OOOOOO",
"OOOOOOOO.OOOOOOO",
"OOOOOOOOOOOOOOOO"
};

1591
src/game.cpp Normal file

File diff suppressed because it is too large Load Diff

127
src/game.h Normal file
View File

@@ -0,0 +1,127 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef GAME_H
#define GAME_H
#include <string>
#include <stdio.h>
#include "global.h"
using namespace std;
typedef struct {
char Filename[12]; //[*]vol.*
long Loc; //location in vol file
bool Exists;
}TResourceInfo ;
#define MaxResourceSize 65530
typedef struct {
byte *Data;
int Size;
}TResource;
class Game
{
public:
Game();
int open(string name);
int newgame(string name);
int from_template(string name);
int close();
void save_settings();
void read_settings();
void defaults();
void make_source_dir();
int GetResourceSize(char ResType,int ResNum);
int ReadResource(char ResourceType, int ResourceID);
int AddResource(int ResType,int ResNum);
int DeleteResource(int ResType,int ResNum);
int RebuildVOLfiles();
int RecompileAll();
TResourceInfo ResourceInfo[4][256]; //logic, picture, view, sound
string dir; //game directory
string ID; //game ID for V3 games (always 'V2' for V2 games)
string dirname; //name of the 'directory' file
//(e.g. picdir, snddir for V2, [ID]dir for V3)
string srcdir; //dir for saving logic sources
bool isOpen,isV3;
//defaults; some GUI defauts are part of GAME object because it is the
//only object which is guaranteed to exist at the beginning of the program
int res_default; //default resource type in resources window
int picstyle; //Picedit style
bool save_logic_as_text; //default for 'extract' function
bool show_all_messages; //logic decompile - show all messages at end
//or just unused ones
bool show_elses_as_gotos;
bool show_special_syntax; //v30=4 vs assignn(v30,4)
bool reldir; //if the source dir is relative to the game dir or absolute
string command; //interpreter command line
string srcdirname; //source dir as entered in options
//(i.e. either relative or absolute; srcdir is always absolute)
string templatedir; //template game directory
string helpdir; //help directory
private:
double AGIVersionNumber;
string FindAGIV3GameID(const char *name);
double GetAGIVersionNumber(void);
int ReadV3Resource(char ResourceType,int ResourceID);
FILE *OpenPatchVol(int PatchVol,int *filesize);
FILE *OpenDirUpdate(int *dirsize,int ResType);
};
extern Game *game;
extern const char *ResTypeName[4];
extern const char *ResTypeAbbrv[4];
extern TResource ResourceData;
extern const char EncryptionKey[];
#define MAX_TMP 2048
extern char tmp[];
//resource types
//(the numbers assigned to these defines are important !)
#define LOGIC 0
#define PICTURE 1
#define VIEW 2
#define SOUND 3
//additional resource types
#define OBJECT 4
#define WORDS 5
#define TEXT 6
#define RESOURCES 7
#define PREVIEW 8
#define HELPWIN 9
//Picedit styles (tools and picture in one window or in separate windows (for small displays))
#define P_ONE 0
#define P_TWO 1
#endif //GAME_H

28
src/global.h Normal file
View File

@@ -0,0 +1,28 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
typedef unsigned char byte;
#ifndef __GNUC__
using namespace std;
#endif
namespace Qt {}
using namespace Qt;

371
src/helpwindow.cpp Normal file
View File

@@ -0,0 +1,371 @@
/****************************************************************************
**
** This help window was modified from an example code by QT.
** Original license:
**
** Copyright (C) 1992-1999 Troll Tech AS. All rights reserved.
**
** This file is part of an example program for Qt. This example
** program may be used, distributed and modified without limitation.
**
*****************************************************************************/
//my modifications of the original source:
//included .xpm in the source, removed 'about' buttons, added setSource,
//removed tr() (didn't compile with Mandrake 7.0)
//added hideEvent,showEvent
#include "helpwindow.h"
#include <qstatusbar.h>
#include <qpixmap.h>
#include <q3popupmenu.h>
#include <qmenubar.h>
#include <q3toolbar.h>
#include <qtoolbutton.h>
#include <qicon.h>
#include <qfile.h>
#include <q3textstream.h>
#include <q3stylesheet.h>
#include <qmessagebox.h>
#include <q3filedialog.h>
#include <qapplication.h>
#include <qcombobox.h>
#include <qevent.h>
#include <qlineedit.h>
#include <qobject.h>
#include <qfileinfo.h>
#include <qfile.h>
#include <qdatastream.h>
//Added by qt3to4:
#include <QShowEvent>
#include <Q3Frame>
#include <QHideEvent>
#include <QKeyEvent>
#include <ctype.h>
#include "home.xpm"
#include "forward.xpm"
#include "back.xpm"
#include "menu.h"
HelpWindow *helpwindow,*helpwindow1;
HelpWindow::HelpWindow( const QString& home_, const QString& _path, QWidget* parent, const char *name )
: Q3MainWindow( parent, name ), pathCombo( 0 ), selectedURL(),
path( QFileInfo( home_ ).dirPath( TRUE ), "*.htm*" )
{
Q3StyleSheetItem* style;
// Modify the application-wide default style sheet to handle
// some extra HTML gracefully.
//
// Ignore any bodytext in <head>...</head>:
style = new Q3StyleSheetItem( Q3StyleSheet::defaultSheet(), "head" );
style->setDisplayMode(Q3StyleSheetItem::DisplayNone);
//
// Not in default style sheet, just fake it:
style = new Q3StyleSheetItem( Q3StyleSheet::defaultSheet(), "dl" );
style->setDisplayMode(Q3StyleSheetItem::DisplayBlock);
style = new Q3StyleSheetItem( Q3StyleSheet::defaultSheet(), "dt" );
style->setDisplayMode(Q3StyleSheetItem::DisplayBlock);
style->setContexts("dl");
//
// Many HTML files omit the </p> or </li>, so we add this for efficiency:
Q3StyleSheet::defaultSheet()->item("p")->setSelfNesting( FALSE );
Q3StyleSheet::defaultSheet()->item("li")->setSelfNesting( FALSE );
readHistory();
readBookmarks();
fileList = path.entryList();
browser = new Q3TextBrowser( this );
browser->mimeSourceFactory()->setFilePath( _path );
browser->setFrameStyle( Q3Frame::Panel | Q3Frame::Sunken );
connect( browser, SIGNAL( textChanged() ),
this, SLOT( textChanged() ) );
setCentralWidget( browser );
if ( !home_.isEmpty() )
browser->setSource( home_ );
connect( browser, SIGNAL( highlighted( const QString&) ),
statusBar(), SLOT( message( const QString&)) );
resize( 640,700 );
Q3PopupMenu* file = new Q3PopupMenu( this );
file->insertItem( "&New Window", this, SLOT( newWindow() ), Qt::ALT | Qt::Key_N );
file->insertItem( "&Open File", this, SLOT( openFile() ), Qt::ALT | Qt::Key_O );
file->insertSeparator();
file->insertItem( "&Close", this, SLOT( hide() ), Qt::ALT | Qt::Key_Q );
Q3PopupMenu* go = new Q3PopupMenu( this );
backwardId = go->insertItem( QPixmap(back),
"&Backward", browser, SLOT( backward() ),
Qt::ALT | Qt::Key_Left );
forwardId = go->insertItem( QPixmap(forward),
"&Forward", browser, SLOT( forward() ),
Qt::ALT | Qt::Key_Right );
go->insertItem( QPixmap(home), "&Home", browser, SLOT( home() ) );
hist = new Q3PopupMenu( this );
QStringList::Iterator it = history.begin();
for ( ; it != history.end(); ++it )
mHistory[ hist->insertItem( *it ) ] = *it;
connect( hist, SIGNAL( activated( int ) ),
this, SLOT( histChosen( int ) ) );
bookm = new Q3PopupMenu( this );
bookm->insertItem( "Add Bookmark", this, SLOT( addBookmark() ) );
bookm->insertSeparator();
QStringList::Iterator it2 = bookmarks.begin();
for ( ; it2 != bookmarks.end(); ++it2 )
mBookmarks[ bookm->insertItem( *it2 ) ] = *it2;
connect( bookm, SIGNAL( activated( int ) ),
this, SLOT( bookmChosen( int ) ) );
menuBar()->insertItem( "&File", file );
menuBar()->insertItem( "&Go", go );
menuBar()->insertItem( "History" , hist );
menuBar()->insertItem( "Bookmarks" , bookm );
menuBar()->setItemEnabled( forwardId, FALSE);
menuBar()->setItemEnabled( backwardId, FALSE);
connect( browser, SIGNAL( backwardAvailable( bool ) ),
this, SLOT( setBackwardAvailable( bool ) ) );
connect( browser, SIGNAL( forwardAvailable( bool ) ),
this, SLOT( setForwardAvailable( bool ) ) );
Q3ToolBar* toolbar = new Q3ToolBar( this );
addToolBar( toolbar, "Toolbar");
QToolButton* button;
button = new QToolButton( QPixmap(back), "Backward", "", browser, SLOT(backward()), toolbar );
connect( browser, SIGNAL( backwardAvailable(bool) ), button, SLOT( setEnabled(bool) ) );
button->setEnabled( FALSE );
button = new QToolButton( QPixmap(forward), "Forward", "", browser, SLOT(forward()), toolbar );
connect( browser, SIGNAL( forwardAvailable(bool) ), button, SLOT( setEnabled(bool) ) );
button->setEnabled( FALSE );
button = new QToolButton( QPixmap(home), "Home", "", browser, SLOT(home()), toolbar );
toolbar->addSeparator();
pathCombo = new QComboBox( TRUE, toolbar );
connect( pathCombo, SIGNAL( activated( const QString & ) ),
this, SLOT( pathSelected( const QString & ) ) );
toolbar->setStretchableWidget( pathCombo );
setRightJustification( TRUE );
pathCombo->insertItem( home_ );
pathCombo->installEventFilter( this );
QObjectList l = queryList( "QLineEdit" );
if ( l.size()>0 )
( (QLineEdit*)l.at(0) )->installEventFilter( this );
browser->setFocus();
}
void HelpWindow::setBackwardAvailable( bool b)
{
menuBar()->setItemEnabled( backwardId, b);
}
void HelpWindow::setForwardAvailable( bool b)
{
menuBar()->setItemEnabled( forwardId, b);
}
void HelpWindow::textChanged()
{
if ( browser->documentTitle().isNull() )
setCaption( browser->context() );
else
setCaption( browser->documentTitle() ) ;
selectedURL = caption();
if ( !selectedURL.isEmpty() && pathCombo ) {
path = QDir( QFileInfo( selectedURL ).dirPath( TRUE ), "*.htm*" );
fileList = path.entryList();
bool exists = FALSE;
int i;
for ( i = 0; i < pathCombo->count(); ++i ) {
if ( pathCombo->text( i ) == selectedURL ) {
exists = TRUE;
break;
}
}
if ( !exists ) {
pathCombo->insertItem( selectedURL, 0 );
pathCombo->setCurrentItem( 0 );
mHistory[ hist->insertItem( selectedURL ) ] = selectedURL;
} else
pathCombo->setCurrentItem( i );
selectedURL = QString::null;
}
}
HelpWindow::~HelpWindow()
{
history.clear();
QMap<int, QString>::Iterator it = mHistory.begin();
for ( ; it != mHistory.end(); ++it )
history.append( *it );
QFile f( QDir::currentDirPath() + "/.history" );
f.open( QIODevice::WriteOnly );
QDataStream s( &f );
s << history;
f.close();
bookmarks.clear();
QMap<int, QString>::Iterator it2 = mBookmarks.begin();
for ( ; it2 != mBookmarks.end(); ++it2 )
bookmarks.append( *it2 );
QFile f2( QDir::currentDirPath() + "/.bookmarks" );
f2.open( QIODevice::WriteOnly );
QDataStream s2( &f2 );
s2 << bookmarks;
f2.close();
}
void HelpWindow::openFile()
{
QString fn = Q3FileDialog::getOpenFileName( QString::null, QString::null, this );
if ( !fn.isEmpty() )
browser->setSource( fn );
}
void HelpWindow::setSource(char *filename)
{
browser->setSource( filename );
}
void HelpWindow::newWindow()
{
( new HelpWindow(browser->source(), "qbrowser") )->show();
}
void HelpWindow::pathSelected( const QString &_path )
{
browser->setSource( _path );
path = QDir( QFileInfo( _path ).dirPath( TRUE ), "*.htm*" );
fileList = path.entryList();
QMap<int, QString>::Iterator it = mHistory.begin();
bool exists = FALSE;
for ( ; it != mHistory.end(); ++it ) {
if ( *it == _path ) {
exists = TRUE;
break;
}
}
if ( !exists )
mHistory[ hist->insertItem( _path ) ] = _path;
}
bool HelpWindow::eventFilter( QObject * o, QEvent * e )
{
QObjectList l = queryList( "QLineEdit" );
if ( l.empty() )
return FALSE;
QLineEdit *lined = (QLineEdit*)l.at(0);
if ( ( o == pathCombo || o == lined ) &&
e->type() == QEvent::KeyPress ) {
if ( isprint(((QKeyEvent *)e)->ascii()) ) {
if ( lined->hasMarkedText() )
lined->del();
QString nt( lined->text() );
nt.remove( 0, nt.findRev( '/' ) + 1 );
nt.truncate( lined->cursorPosition() );
nt += (char)(((QKeyEvent *)e)->ascii());
QStringList::Iterator it = fileList.begin();
while ( it != fileList.end() && (*it).left( nt.length() ) != nt )
++it;
if ( !(*it).isEmpty() ) {
nt = *it;
int cp = lined->cursorPosition() + 1;
int l = path.canonicalPath().length() + 1;
lined->validateAndSet( path.canonicalPath() + "/" + nt, cp, cp, l + nt.length() );
return TRUE;
}
}
}
return FALSE;
}
void HelpWindow::readHistory()
{
if ( QFile::exists( QDir::currentDirPath() + "/.history" ) ) {
QFile f( QDir::currentDirPath() + "/.history" );
f.open( QIODevice::ReadOnly );
QDataStream s( &f );
s >> history;
f.close();
while ( history.count() > 20 )
history.remove( history.begin() );
}
}
void HelpWindow::readBookmarks()
{
if ( QFile::exists( QDir::currentDirPath() + "/.bookmarks" ) ) {
QFile f( QDir::currentDirPath() + "/.bookmarks" );
f.open( QIODevice::ReadOnly );
QDataStream s( &f );
s >> bookmarks;
f.close();
}
}
void HelpWindow::histChosen( int i )
{
if ( mHistory.contains( i ) )
browser->setSource( mHistory[ i ] );
}
void HelpWindow::bookmChosen( int i )
{
if ( mBookmarks.contains( i ) )
browser->setSource( mBookmarks[ i ] );
}
void HelpWindow::addBookmark()
{
mBookmarks[ bookm->insertItem( caption() ) ] = caption();
}
//*********************************************
void HelpWindow::hideEvent( QHideEvent * )
{
if(window_list && window_list->isVisible())window_list->draw();
}
//*********************************************
void HelpWindow::showEvent( QShowEvent * )
{
if(window_list && window_list->isVisible())window_list->draw();
}

70
src/helpwindow.h Normal file
View File

@@ -0,0 +1,70 @@
/****************************************************************************
** $Id: helpwindow.h 44 2012-08-17 19:22:03Z elonen $
**
** Copyright (C) 1992-1999 Troll Tech AS. All rights reserved.
**
** This file is part of an example program for Qt. This example
** program may be used, distributed and modified without limitation.
**
*****************************************************************************/
#ifndef HELPWINDOW_H
#define HELPWINDOW_H
#include <q3textbrowser.h>
#include <q3mainwindow.h>
#include <qstringlist.h>
#include <qmap.h>
#include <qdir.h>
//Added by qt3to4:
#include <Q3PopupMenu>
#include <QShowEvent>
#include <QHideEvent>
#include <QEvent>
class QComboBox;
class Q3PopupMenu;
class HelpWindow : public Q3MainWindow
{
Q_OBJECT
public:
HelpWindow( const QString& home_, const QString& path, QWidget* parent = 0, const char *name=0 );
~HelpWindow();
void setSource(char *filename);
private slots:
void setBackwardAvailable( bool );
void setForwardAvailable( bool );
void textChanged();
void openFile();
void newWindow();
void pathSelected( const QString & );
void histChosen( int );
void bookmChosen( int );
void addBookmark();
void showEvent( QShowEvent * );
void hideEvent( QHideEvent * );
private:
bool eventFilter( QObject * o, QEvent * e );
void readHistory();
void readBookmarks();
Q3TextBrowser* browser;
QComboBox *pathCombo;
int backwardId, forwardId;
QString selectedURL;
QDir path;
QStringList fileList, history, bookmarks;
QMap<int, QString> mHistory, mBookmarks;
Q3PopupMenu *hist, *bookm;
};
extern HelpWindow *helpwindow,*helpwindow1;
#endif

26
src/home.xpm Normal file
View File

@@ -0,0 +1,26 @@
/* XPM */
static const char *home[] = {
/* columns rows colors chars-per-pixel */
"16 16 4 1",
" c black",
". c #C0C0C0C0C0C0",
"X c gray100",
"o c None",
/* pixels */
"oooooooooooooooo",
"ooooooo ooooooo",
"oo ooo oooooo",
"oo oo XX.. ooooo",
"oo o XXXX.. oooo",
"oo XXXXXX.. ooo",
"oo XXXXXXXX.. oo",
"o XXXXXXXXX... o",
" XXXXXXXX.. ",
"oo XXXXXXXX.. oo",
"oo XXX XX.. oo",
"oo XXX o XX.. oo",
"oo XXX o XX.. oo",
"oo XXX o XX.. oo",
"oo XXX o XX.. oo",
"oo o oo"
};

BIN
src/icon1.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

24
src/left.xpm Normal file
View File

@@ -0,0 +1,24 @@
/* XPM */
static const char *left[] = {
/* columns rows colors chars-per-pixel */
"16 16 2 1",
" c black",
". c gray100",
/* pixels */
"................",
"................",
".......... ....",
"......... ....",
"........ ....",
"....... ....",
"...... ....",
"..... ....",
"..... ....",
"...... ....",
"....... ....",
"........ ....",
"......... ....",
".......... ....",
"................",
"................"
};

24
src/left1.xpm Normal file
View File

@@ -0,0 +1,24 @@
/* XPM */
static const char *left1[] = {
/* columns rows colors chars-per-pixel */
"16 16 2 1",
" c black",
". c gray100",
/* pixels */
"................",
"................",
"........ ....",
"....... .....",
"...... ......",
"..... .......",
".... ........",
"... .........",
"... .........",
".... ........",
"..... .......",
"...... ......",
"....... .....",
"........ ....",
"................",
"................"
};

24
src/left1_x.xpm Normal file
View File

@@ -0,0 +1,24 @@
/* XPM */
static const char *left1_x[] = {
/* columns rows colors chars-per-pixel */
"16 16 2 1",
" c black",
". c None",
/* pixels */
"................",
"................",
"........ ....",
"....... .....",
"...... ......",
"..... .......",
".... ........",
"... .........",
"... .........",
".... ........",
"..... .......",
"...... ......",
"....... .....",
"........ ....",
"................",
"................"
};

24
src/left2.xpm Normal file
View File

@@ -0,0 +1,24 @@
/* XPM */
static const char *left2[] = {
/* columns rows colors chars-per-pixel */
"16 16 2 1",
" c black",
". c gray100",
/* pixels */
"................",
"................",
"...... ... .",
"..... ... ..",
".... ... ...",
"... ... ....",
".. ... .....",
". ... ......",
". ... ......",
".. ... .....",
"... ... ....",
".... ... ...",
"..... ... ..",
"...... ... .",
"................",
"................"
};

24
src/left2_x.xpm Normal file
View File

@@ -0,0 +1,24 @@
/* XPM */
static const char *left2_x[] = {
/* columns rows colors chars-per-pixel */
"16 16 2 1",
" c black",
". c None",
/* pixels */
"................",
"................",
"...... ... .",
"..... ... ..",
".... ... ...",
"... ... ....",
".. ... .....",
". ... ......",
". ... ......",
".. ... .....",
"... ... ....",
".... ... ...",
"..... ... ..",
"...... ... .",
"................",
"................"
};

24
src/left_x.xpm Normal file
View File

@@ -0,0 +1,24 @@
/* XPM */
static const char *left_x[] = {
/* columns rows colors chars-per-pixel */
"16 16 2 1",
" c black",
". c None",
/* pixels */
"................",
"................",
".......... ....",
"......... ....",
"........ ....",
"....... ....",
"...... ....",
"..... ....",
"..... ....",
"...... ....",
"....... ....",
"........ ....",
"......... ....",
".......... ....",
"................",
"................"
};

24
src/leftarrow_x.xpm Normal file
View File

@@ -0,0 +1,24 @@
/* XPM */
static const char *leftarrow_x[] = {
/* columns rows colors chars-per-pixel */
"16 16 2 1",
" c black",
". c None",
/* pixels */
"....... .......",
"...... .......",
"..... .......",
".... .......",
"... .......",
".. .......",
". .",
" .",
" .",
". .",
".. .......",
"... .......",
".... .......",
"..... .......",
"...... .......",
"....... ......."
};

282
src/linklist.cpp Normal file
View File

@@ -0,0 +1,282 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
/*************************************************************************
** linklist.c
**
** The AGI PICTURE codes will be stored in a doubly linked list which
** will make the editing a lot more simple and quicker.
**
** (c) Lance Ewing 1997
*************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "linklist.h"
#include "picture.h"
void Picture::dldelete()
{
struct picCodeNode *temp;
if (picPos == NULL) return;
if (picPos == picStart) picStart = picPos->next;
if (picPos == picLast) picLast = picPos->prior;
if (picPos->prior != NULL) {
picPos->prior->next = picPos->next;
}
if (picPos->next != NULL) {
picPos->next->prior = picPos->prior;
}
temp = picPos->next;
free(picPos);
picPos = temp;
bufLen--;
/* bufPos should still be the same */
}
void Picture::removeAction()
{
if (picPos != NULL) {
dldelete();
while ((picPos != NULL) && (picPos->node < 0xF0)) dldelete();
}
}
void Picture::wipeAction()
{
if (picPos != NULL) {
dldelete();
while (picPos != NULL) dldelete();
}
}
void Picture::dlstore(struct picCodeNode *i)
{
if ((picStart == NULL) && (picLast == NULL)) {
picStart = picLast = i;
i->next = NULL;
i->prior = NULL;
picPos = NULL;
}
else if (picPos == NULL) { // End Node
i->next = NULL;
i->prior = picLast;
picLast->next = i;
picLast = i;
picPos = NULL;
}
else {
switch (addMode) {
case INS_MODE:
i->prior = picPos->prior; // works for picStart as well
i->next = picPos;
if (picPos != picStart) picPos->prior->next = i;
if (picPos == picStart) picStart = i;
picPos->prior = i;
// picPos = i;
break;
case OVR_MODE:
i->prior = picPos->prior; // link from i
i->next = picPos->next;
if (picPos != picStart) picPos->prior->next = i;
if (picPos == picStart) picStart = i;
if (picPos != picLast) picPos->next->prior = i;
if (picPos == picLast) picLast = i;
free(picPos);
picPos = i->next;
break;
}
}
bufLen++;
bufPos++;
}
void Picture::displayList()
{
struct picCodeNode *temp;
temp = picStart;
printf("%02X ", temp->node);
do {
temp = temp->next;
printf("%X ", temp->node);
} while (temp->next != NULL);
printf("\n");
}
void Picture::freeList()
{
struct picCodeNode *temp, *store;
if ((picStart != NULL) && (picLast != NULL)) {
temp = picStart;
store = temp->next;
free(temp);
do {
temp = store;
store = temp->next;
free(temp);
} while (store != NULL);
picStart = picLast = picPos = NULL;
}
bufPos = 0;
bufLen = 0;
}
void Picture::moveBack()
{
if (picPos == NULL) {
picPos = picLast;
if (bufPos > 0) bufPos--;
}
else {
if (picPos->prior != NULL) {
picPos = picPos->prior;
bufPos--;
}
}
}
void Picture::moveForward()
{
if (picPos !=NULL) {
picPos = picPos->next;
bufPos++;
}
}
void Picture::moveToStart()
{
picPos = picStart;
bufPos = 0;
}
void Picture::moveToEnd()
{
picPos = NULL;
bufPos = bufLen;
}
void Picture::moveBackAction()
{
do {
moveBack();
if (picPos == picStart) break;
} while (picPos->node < 0xF0);
}
void Picture::moveForwardAction()
{
do {
moveForward();
if (picPos == NULL) break;
} while (picPos->node < 0xF0);
}
/* LIST TEST PROGRAM
void main()
{
struct picCodeNode *trial, *trial2, *trial3, *temp;
int i;
trial = (struct picCodeNode *)malloc(sizeof(picCodes));
trial2 = (struct picCodeNode *)malloc(sizeof(picCodes));
trial3 = (struct picCodeNode *)malloc(sizeof(picCodes));
trial->node = 0x64;
trial2->node = 0x50;
trial3->node = 0x40;
dlstore(trial);
dlstore(trial2);
dlstore(trial3);
for (i=0; i<10; i++) {
temp = (struct picCodeNode *)malloc(sizeof(picCodes));
temp->node = i;
dlstore(temp);
}
clrscr();
displayList();
moveBack();
temp = (struct picCodeNode *)malloc(sizeof(picCodes));
temp->node = 0x3F;
dlstore(temp);
displayList();
moveBack();
moveBack();
moveBack();
addMode = OVR_MODE;
temp = (struct picCodeNode *)malloc(sizeof(picCodes));
temp->node = 0x4F;
dlstore(temp);
displayList();
moveToStart();
temp = (struct picCodeNode *)malloc(sizeof(picCodes));
temp->node = 0x8F;
dlstore(temp);
displayList();
moveToStart();
addMode = INS_MODE;
temp = (struct picCodeNode *)malloc(sizeof(picCodes));
temp->node = 0x7F;
dlstore(temp);
displayList();
moveForward();
moveForward();
moveForward();
moveForward();
temp = (struct picCodeNode *)malloc(sizeof(picCodes));
temp->node = 0x6F;
dlstore(temp);
displayList();
moveToEnd();
temp = (struct picCodeNode *)malloc(sizeof(picCodes));
temp->node = 0x5F;
dlstore(temp);
displayList();
freeList();
}
*/

37
src/linklist.h Normal file
View File

@@ -0,0 +1,37 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
/**************************************************************************
** linklist.h (by Lance Ewing)
**************************************************************************/
#ifndef _LINKLIST_H_
#define _LINKLIST_H_
#define INS_MODE 0
#define OVR_MODE 1
struct picCodeNode {
unsigned char node;
struct picCodeNode *next;
struct picCodeNode *prior;
};
#endif /* _LINKLIST_H_ */

1508
src/logcompile.cpp Normal file

File diff suppressed because it is too large Load Diff

685
src/logdecode.cpp Normal file
View File

@@ -0,0 +1,685 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
* Almost all of this code was adapted from the Windows AGI Studio
* developed by Peter Kelly.
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include "game.h"
#include "logedit.h"
#include "words.h"
#include "object.h"
#include "menu.h"
#include "agicommands.h"
#include <cstdlib>
#include <stdio.h>
static int EncryptionStart;
static int MessageSectionStart,MessageSectionEnd;
static bool MessageUsed[256],MessageExists[256];
static int ResPos;
static byte CurByte;
static int NumMessages;
static string Messages[MaxMessages];
static byte ThisCommand;
bool ShowArgTypes = true;
bool ShowNonExistingValues = true; // Uses the number of an object, word or message instead of the text if it does not exist
byte SpecialSyntaxType = 1; // 0 for v30 = v30 + 4;, 1 for v30 += 4;
static byte BlockDepth;
static short BlockEnd[MaxBlockDepth+1];
static short BlockLength[MaxBlockDepth+1];
static bool BlockIsIf[MaxBlockDepth+1];
static short TempBlockLength,CurBlock;
static byte CurArg;
static unsigned int ArgsStart;
static TResource LabelIndex;
static int LabelLoc,NumLabels;
static bool DoGoto;
static string ThisLine;
static bool ErrorOccured;
static bool FirstCommand, OROn , NOTOn;
static byte NumSaidArgs;
static byte IndentPos;
//***************************************************
static byte ReadByte(void)
{
if(ResPos < ResourceData.Size){
return ResourceData.Data[ResPos++];
}
return 0;
}
//***************************************************
static short ReadLSMSWord(void)
{
byte MSbyte,LSbyte;
LSbyte = ReadByte();
MSbyte = ReadByte();
return ((MSbyte<<8)|LSbyte);
}
//***************************************************
static byte ReadEncByte(void)
{
return (ReadByte() ^ EncryptionKey[(ResPos-EncryptionStart+10)%11]) ;
}
//***************************************************
void Logic::ReadMessages(void)
{
int MessageStart[256];
string ThisMessage;
int i;
// NOTE: There is no message 0 (this is not supported by the file format).
for(i=0;i<MaxMessages;i++){
Messages[i]="";
MessageExists[i] = false;
MessageUsed[i] = false;
}
ResPos = MessageSectionStart;
NumMessages = ReadByte();
if (NumMessages > 0){
MessageSectionEnd = ReadLSMSWord() + MessageSectionStart;
for (i = 1;i <= NumMessages;i++){
MessageStart[i] = ReadLSMSWord();
}
EncryptionStart = ResPos;
for (i = 1;i <= NumMessages;i++){
if (MessageStart[i] > 0){
ThisMessage = "";
ResPos = MessageSectionStart + MessageStart[i] + 1;
do{
CurByte = ReadEncByte();
if (CurByte == 0 || ResPos >= ResourceData.Size)break;
if(CurByte == 0x0a)ThisMessage += "\\n";
else if (CurByte == 0x22)ThisMessage += "\\\"";
else if (CurByte == 0x5c)ThisMessage += "\\\\";
else ThisMessage += CurByte;
}while(true);
Messages[i]=ThisMessage;
MessageExists[i] = true;
}
}
}
}
//***************************************************
void Logic::DisplayMessages(void)
{
int i;
if(game->show_all_messages){
OutputText.append("// Messages\n");
for(i=1;i<=255;i++){
if (MessageExists[i]){
OutputText.append("#message " + IntToStr(i) + " \""+Messages[i]+"\"\n");
}
}
}
else{ //(only those not used elsewhere in the logic are here)
OutputText.append("// Messages\n");
for(i=1;i<=255;i++){
if (MessageExists[i] && !MessageUsed[i]){
OutputText.append("#message " + IntToStr(i)+" \""+Messages[i]+"\"\n");
}
}
}
}
//***************************************************
int Logic::FindLabels_ReadIfs(void)
{
byte NumSaidArgs;
do{
CurByte = ReadByte();
if(CurByte == 0xFC)CurByte = ReadByte();
if(CurByte == 0xFC)CurByte = ReadByte(); // we may have 2 0xFCs in a row, e.g. (a || b) && (c || d)
if(CurByte == 0xFD)CurByte = ReadByte();
if (CurByte > 0 && CurByte <= NumTestCommands){
ThisCommand = CurByte;
if (ThisCommand == 14){ // said command
NumSaidArgs = ReadByte();
ResPos += NumSaidArgs*2;
}
else{
ResPos += TestCommand[ThisCommand].NumArgs;
}
}
else if(CurByte == 0xFF){
if (BlockDepth >= MaxBlockDepth - 1){
sprintf(tmp,"Too many nested blocks (%d)\n",BlockDepth);
ErrorList.append(tmp);
ErrorOccured=true;
break;
}
BlockDepth++;
BlockIsIf[BlockDepth] = true;
BlockLength[BlockDepth] = ReadLSMSWord();
BlockEnd[BlockDepth] = BlockLength[BlockDepth] + ResPos;
if (BlockEnd[BlockDepth] > BlockEnd[BlockDepth-1]){
sprintf(tmp,"Block too long (%d bytes longer than rest of previous block)",BlockEnd[BlockDepth]-BlockEnd[BlockDepth-1]);
ErrorOccured=true;
ErrorList.append(string(tmp)+"\n");
}
break;
}
else{
sprintf(tmp,"Unknown test command (%d)",CurByte);
break;
}
}while(true);
return 0;
}
//***************************************************
void Logic::AddBlockEnds(void)
{
for(int CurBlock = BlockDepth;CurBlock>=1;CurBlock--){
if (BlockEnd[CurBlock] <= ResPos){
OutputText.append(MultStr(" ",CurBlock-1)+"}\n");
BlockDepth--;
}
}
}
//***************************************************
int Logic::FindLabels(void)
{
LabelIndex.Size = ResourceData.Size;
LabelIndex.Data = (byte *)calloc(LabelIndex.Size,1);
BlockDepth = 0;
NumLabels = 0;
do{
for( CurBlock = BlockDepth;CurBlock>=1;CurBlock--){
if (BlockEnd[CurBlock] <= ResPos)BlockDepth--;
}
CurByte = ReadByte();
if (CurByte == 0xFF)FindLabels_ReadIfs();
else if(CurByte <= NumAGICommands){
ResPos += AGICommand[CurByte].NumArgs;
}
else if(CurByte == 0xFE){
DoGoto = false;
TempBlockLength = ReadLSMSWord();
if ((BlockEnd[BlockDepth] == ResPos) && (BlockIsIf[BlockDepth]) && (BlockDepth > 0) && (!game->show_elses_as_gotos)){
BlockIsIf[BlockDepth] = false;
if (TempBlockLength + ResPos > BlockEnd[BlockDepth-1] || (TempBlockLength & 0x8000) || BlockLength[BlockDepth] <= 3){
DoGoto = true;
}
else{
BlockLength[BlockDepth] = TempBlockLength;
BlockEnd[BlockDepth] = BlockLength[BlockDepth] + ResPos;
}
}
else{
DoGoto = true;
}
//goto
if (DoGoto){
LabelLoc = TempBlockLength + ResPos;
if (LabelLoc > LabelIndex.Size - 1){
sprintf(tmp,"Label past end of logic (%x %x)\n ",LabelLoc,LabelIndex.Size);
ErrorList.append(tmp);
ErrorOccured=true;
break;
}
if (LabelIndex.Data[LabelLoc] == 0){
NumLabels++;
LabelIndex.Data[LabelLoc] = NumLabels;
}
}
}
else{
sprintf(tmp,"Unknown command (%d)",CurByte);
break;
}
}while(ResPos < MessageSectionStart);
return 0;
}
//***************************************************
void Logic::AddArg(byte Arg, byte ArgType)
{
int NumCharsToDisplay;
string ThisMessage;
if(ShowArgTypes){
switch(ArgType){
case atMsg:
if (MessageExists[Arg]){
string ThisMessage = Messages[Arg];
do{
if(ThisMessage.length() + ThisLine.length() > maxcol){
NumCharsToDisplay = maxcol - ThisLine.length();
do{
NumCharsToDisplay--;
}while(!(NumCharsToDisplay <= 0 || ThisMessage[NumCharsToDisplay]==' '));
if (NumCharsToDisplay <= 0)
NumCharsToDisplay = maxcol-ThisLine.length();
if (NumCharsToDisplay <= 0)
NumCharsToDisplay = ThisMessage.length();
ThisLine += "\"" + ThisMessage.substr(0,NumCharsToDisplay) + "\"";
if(NumCharsToDisplay < (int)ThisMessage.length()){
ThisMessage = ThisMessage.substr(NumCharsToDisplay+1);
OutputText.append(ThisLine+"\n");
}
else{
ThisMessage = "";
OutputText.append(ThisLine);
}
if (ArgsStart >= maxcol - 20)ArgsStart = maxcol - 20;
ThisLine = MultStr(" ",ArgsStart);
}
else{
ThisLine += "\"" + ThisMessage + "\"" ;
ThisMessage = "";
}
}while(ThisMessage.length()>0);
}
else if(ShowNonExistingValues){
ThisLine += ArgTypePrefix[atMsg] + IntToStr(Arg);
}
else{
sprintf(tmp,"Unknown message (%d)\n",Arg);
ErrorList.append(tmp);
ErrorOccured=true;
}
MessageUsed[Arg] = true;
break;
case atIObj:
if (Arg <= objlist->ItemNames.num - 1){
ThisLine += "\"" + objlist->ItemNames.at(Arg) + "\"";
}
else if(ShowNonExistingValues){
ThisLine += ArgTypePrefix[atIObj] + IntToStr(Arg);
}
else{
sprintf(tmp,"Unknown inventory item (%d)\n",Arg);
ErrorList.append(tmp);
ErrorOccured=true;
}
break;
default:
if(ArgType != 0){
ThisLine += ArgTypePrefix[ArgType] + IntToStr(Arg);
}
else{
ThisLine += IntToStr(Arg);
}
break;
}
}
else{
ThisLine += IntToStr(Arg);
}
}
//***************************************************
void Logic::AddSpecialSyntaxCommand(void)
{
int arg1;
arg1 = ReadByte();
switch(ThisCommand){
// increment
case 0x01: ThisLine += "v"+IntToStr(arg1)+"++"; break;
// decrement
case 0x02: ThisLine += "v"+IntToStr(arg1)+"--"; break;
// assignn
case 0x03: ThisLine += "v"+IntToStr(arg1)+" = "+IntToStr(ReadByte()); break;
// assignv
case 0x04: ThisLine += "v"+IntToStr(arg1)+" = v"+IntToStr(ReadByte()); break;
// addn
case 0x05: if (SpecialSyntaxType == 0)
ThisLine += "v"+IntToStr(arg1)+" = v"+IntToStr(arg1)+" + "+IntToStr(ReadByte());
else ThisLine += "v"+IntToStr(arg1)+" += "+IntToStr(ReadByte()); break;
// addv
case 0x06: if (SpecialSyntaxType == 0)
ThisLine += "v"+IntToStr(arg1)+" = v"+IntToStr(arg1)+" + v"+IntToStr(ReadByte());
else ThisLine += "v"+IntToStr(arg1)+" += v"+IntToStr(ReadByte()); break;
// subn
case 0x07: if (SpecialSyntaxType == 0)
ThisLine += "v"+IntToStr(arg1)+" = v"+IntToStr(arg1)+" - "+IntToStr(ReadByte());
else ThisLine += "v"+IntToStr(arg1)+" -= "+IntToStr(ReadByte()); break;
// subv
case 0x08: if (SpecialSyntaxType == 0)
ThisLine += "v"+IntToStr(arg1)+" = v"+IntToStr(arg1)+" - v"+IntToStr(ReadByte());
else ThisLine += "v"+IntToStr(arg1)+" -= v"+IntToStr(ReadByte()); break;
// lindirectv
case 0x09: ThisLine += "*v"+IntToStr(arg1)+" = v"+IntToStr(ReadByte()); break;
// rindirect
case 0x0A: ThisLine += "v"+IntToStr(arg1)+" = *v"+IntToStr(ReadByte()); break;
// lindirectn
case 0x0B: ThisLine += "*v"+IntToStr(arg1)+" = "+IntToStr(ReadByte()); break;
// mul.n
case 0xA5: if (SpecialSyntaxType == 0)
ThisLine += "v"+IntToStr(arg1)+" = v"+IntToStr(arg1)+" * "+IntToStr(ReadByte());
else ThisLine += "v"+IntToStr(arg1)+" *= "+IntToStr(ReadByte()); break;
// mul.v
case 0xA6: if (SpecialSyntaxType == 0)
ThisLine += "v"+IntToStr(arg1)+" = v"+IntToStr(arg1)+" * v"+IntToStr(ReadByte());
else ThisLine += "v"+IntToStr(arg1)+" *= v"+IntToStr(ReadByte()); break;
// div.n
case 0xA7: if (SpecialSyntaxType == 0)
ThisLine += "v"+IntToStr(arg1)+" = v"+IntToStr(arg1)+" / "+IntToStr(ReadByte());
else ThisLine += "v"+IntToStr(arg1)+" /= "+IntToStr(ReadByte()); break;
// div.v
case 0xA8: if (SpecialSyntaxType == 0)
ThisLine += "v"+IntToStr(arg1)+" = v"+IntToStr(arg1)+" / v"+IntToStr(ReadByte());
else ThisLine += "v"+IntToStr(arg1)+" /= v"+IntToStr(ReadByte()); break;
}
}
//***************************************************
void Logic::AddSpecialIFSyntaxCommand(void)
{
switch(ThisCommand){
case 1: // equaln
ThisLine += 'v' + IntToStr(ReadByte());
if (NOTOn) ThisLine += " != ";
else ThisLine += " == ";
ThisLine += IntToStr(ReadByte());
break;
case 2: // equalv
ThisLine += 'v' + IntToStr(ReadByte());
if (NOTOn) ThisLine += " != v";
else ThisLine += " == v";
ThisLine += IntToStr(ReadByte());
break;
case 3: // lessn
ThisLine += 'v' + IntToStr(ReadByte());
if (NOTOn) ThisLine += " >= ";
else ThisLine += " < ";
ThisLine += IntToStr(ReadByte());
break;
case 4: // lessv
ThisLine += 'v' + IntToStr(ReadByte());
if (NOTOn) ThisLine += " >= v";
else ThisLine += " < v";
ThisLine += IntToStr(ReadByte());
break;
case 5: // greatern
ThisLine += 'v' + IntToStr(ReadByte());
if (NOTOn) ThisLine += " <= ";
else ThisLine += " > ";
ThisLine += IntToStr(ReadByte());
break;
case 6: // greaterv
ThisLine += 'v' + IntToStr(ReadByte());
if (NOTOn) ThisLine += " <= v";
else ThisLine += " > v";
ThisLine += IntToStr(ReadByte());
break;
}
}
//***************************************************
void Logic::ReadIfs(void)
{
int ThisWordGroupIndex, ThisWordGroupNum;
FirstCommand = true;
OROn = false;
ThisLine = MultStr(" ",BlockDepth)+"if (";
do{
NOTOn = false;
CurByte = ReadByte();
if (CurByte == 0xFC){
OROn = !OROn;
if (OROn){
if (!FirstCommand){
ThisLine += " &&";
OutputText.append(ThisLine+"\n");
ThisLine = MultStr(" ",BlockDepth)+" ";
FirstCommand = true;
}
ThisLine += '(';
}
else ThisLine += ')';
CurByte = ReadByte();
}
if(CurByte == 0xFC && !OROn){ // we may have 2 0xFCs in a row, e.g. (a || b) && (c || d)
ThisLine += " &&";
OutputText.append(ThisLine+"\n");
ThisLine = MultStr(" ",BlockDepth)+" ";
FirstCommand = true;
ThisLine += "(";
OROn = true;
CurByte = ReadByte();
}
if (CurByte == 0xFD){ // NOT
NOTOn = true;
CurByte = ReadByte();
}
if (CurByte > 0 && CurByte <= NumTestCommands){
if(!FirstCommand){
if (OROn) ThisLine += " ||";
else ThisLine += " &&";
OutputText.append(ThisLine+"\n");
ThisLine = MultStr(" ",BlockDepth)+" ";
}
ThisCommand = CurByte;
if (game->show_special_syntax && ThisCommand >=1 && ThisCommand <=6)
AddSpecialIFSyntaxCommand();
else{
if (NOTOn) ThisLine += '!';
ThisLine += string(TestCommand[ThisCommand].Name) + '(';
ArgsStart = ThisLine.length();
if (ThisCommand == 14){ // said command
NumSaidArgs = ReadByte();
for (CurArg = 1;CurArg<=NumSaidArgs; CurArg++){
ThisWordGroupNum = ReadLSMSWord();
ThisWordGroupIndex = wordlist->GetWordGroupIndex(ThisWordGroupNum);
if (ThisWordGroupIndex < 0){
if (ShowNonExistingValues){
ThisLine += IntToStr(ThisWordGroupNum);
}
else{
sprintf(tmp,"Unknown word group (%d)\n",ThisWordGroupNum);
ErrorList.append(tmp);
ErrorOccured=true;
break;
}
}
else{
ThisLine += '"' + string(wordlist->WordGroup[ThisWordGroupIndex].Words.at(0)) + '"';
if (CurArg < NumSaidArgs)ThisLine += ',';
}
}
}
else{
for (CurArg = 0; CurArg < TestCommand[ThisCommand].NumArgs; CurArg++){
CurByte = ReadByte();
AddArg(CurByte,TestCommand[ThisCommand].argTypes[CurArg]);
if (CurArg < TestCommand[ThisCommand].NumArgs-1)ThisLine += ',';
}
} // if ThisCommand != 14
ThisLine += ')';
}
FirstCommand = false;
}//if (CurByte > 0) && (CurByte <= NumTestCommands)
else if (CurByte == 0xff){
ThisLine += ") {";
if (BlockDepth >= MaxBlockDepth - 1){
sprintf(tmp,"Too many nested blocks (%d)\n",BlockDepth);
ErrorList.append(tmp);
ErrorOccured=true;
break;
}
else{
BlockDepth++;
BlockIsIf[BlockDepth] = true;
BlockLength[BlockDepth] = ReadLSMSWord();
BlockEnd[BlockDepth] = BlockLength[BlockDepth] + ResPos;
if (BlockEnd[BlockDepth] > BlockEnd[BlockDepth-1]){
sprintf(tmp,"Block too long (%d bytes longer than rest of previous block)\n",BlockEnd[BlockDepth]-BlockEnd[BlockDepth-1]);
ErrorList.append(tmp);
ErrorOccured=true;
break;
}
}
OutputText.append(ThisLine+"\n");
ThisLine = MultStr(" ",BlockDepth);
break;
}// if CurByte = 0xFF
else{
sprintf(tmp,"Unknown test command (%d)\n",CurByte);
ErrorList.append(tmp);
ErrorOccured=true;
break;
}
}while(!ErrorOccured);
}
//***************************************************
int Logic::decode(int ResNum)
{
int ret=0,i,j;
OutputText = "";
sprintf(tmp,"%s/words.tok",game->dir.c_str());
ret = wordlist->read(tmp);
if(ret)return 1;
sprintf(tmp,"%s/object",game->dir.c_str());
ret = objlist->read(tmp,false);
if(ret)return 1;
objlist->ItemNames.toLower();
// words already in lower case in file so we don't need to convert them
for(i=0;i<objlist->ItemNames.num;i++){
if(objlist->ItemNames.at(i).find_first_of("\"")==string::npos)continue;
//replace " with \"
char *ptr=(char *)objlist->ItemNames.at(i).c_str();
for(j=0;*ptr;ptr++){
if(*ptr=='"'){
tmp[j++]='\\';
tmp[j++]='"';
}
else tmp[j++]=*ptr;
}
tmp[j]=0;
objlist->ItemNames.replace(i,tmp);
}
ret = game->ReadResource(LOGIC,ResNum);
if(ret)return 1;
ErrorList="";
ResPos = 0;
MessageSectionStart = ReadLSMSWord() + 2;
if (MessageSectionStart > ResourceData.Size - 1){
sprintf(tmp,"Error: Message section start %x is beyond end of resource\n",
MessageSectionStart);
ErrorList.append(tmp);
return 1;
}
ErrorOccured=false;
ReadMessages();
ResPos = 2;
BlockEnd[0] = MessageSectionStart;
BlockIsIf[0] = false;
memset(BlockIsIf,0,sizeof(BlockIsIf));
FindLabels();
BlockDepth = 0;
ResPos = 2;
do{
AddBlockEnds();
if (LabelIndex.Data[ResPos] > 0){
OutputText.append("Label" + IntToStr(LabelIndex.Data[ResPos]) + ":\n");
}
CurByte = ReadByte();
if(CurByte == 0xFF)ReadIfs();
else if(CurByte <= NumAGICommands){
ThisCommand = CurByte;
ThisLine = MultStr(" ",BlockDepth);
if (game->show_special_syntax && (ThisCommand>=0x01 && ThisCommand<=0x0B)||(ThisCommand>=0xA5&&ThisCommand<=0xA8))AddSpecialSyntaxCommand();
else{
ThisLine+=(string(AGICommand[ThisCommand].Name) + "(");
ArgsStart = ThisLine.length();
IndentPos = ThisLine.length();
for(CurArg = 1;CurArg<=AGICommand[ThisCommand].NumArgs;CurArg++){
CurByte = ReadByte();
AddArg(CurByte,AGICommand[ThisCommand].argTypes[CurArg-1]);
if(CurArg < AGICommand[ThisCommand].NumArgs)ThisLine+=",";
}
ThisLine+=")";
}
ThisLine+=";";
OutputText.append(ThisLine+"\n");
}
else if(CurByte == 0xfe){
DoGoto = false;
TempBlockLength = ReadLSMSWord();
if (BlockEnd[BlockDepth] == ResPos && (BlockIsIf[BlockDepth]) && BlockDepth > 0 && (!game->show_elses_as_gotos)){
//else
BlockIsIf[BlockDepth] = false;
if (TempBlockLength + ResPos > BlockEnd[BlockDepth-1] || TempBlockLength & 0x8000 || BlockLength[BlockDepth] <= 3){
DoGoto = true;
}
else{
OutputText.append(MultStr(" ",BlockDepth-1) + "}\n");
OutputText.append(MultStr(" ",BlockDepth-1) + "else {\n");
BlockLength[BlockDepth] = TempBlockLength;
BlockEnd[BlockDepth] = BlockLength[BlockDepth] + ResPos;
}
}
else DoGoto = true;
// goto
if (DoGoto){
LabelLoc = TempBlockLength + ResPos;
if (LabelLoc > LabelIndex.Size - 1){
sprintf(tmp,"Label past end of logic (%x %x)\n ",LabelLoc,LabelIndex.Size);
ErrorList.append(tmp);
ErrorOccured=true;
break;
}
else{
OutputText.append(MultStr(" ",BlockDepth) + "goto(Label"+IntToStr(LabelIndex.Data[LabelLoc])+");\n");
}
}
}
else{
sprintf(tmp,"Unknown action command (%d)\n",CurByte);
ErrorList.append(tmp);
ErrorOccured = true;
break;
}
}while(ResPos < MessageSectionStart);
if(!ErrorOccured)AddBlockEnds();
free(LabelIndex.Data);
OutputText.append("\n");
DisplayMessages();
return (ErrorOccured)?1:0;
}

1436
src/logedit.cpp Normal file

File diff suppressed because it is too large Load Diff

147
src/logedit.h Normal file
View File

@@ -0,0 +1,147 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef LOGEDIT_H
#define LOGEDIT_H
#include <qwidget.h>
#include <qlabel.h>
#include <qpushbutton.h>
#include <qlayout.h>
#include <qnamespace.h>
#include <qmessagebox.h>
#include <q3multilineedit.h>
#include <qevent.h>
#include <qstatusbar.h>
#include <qcheckbox.h>
//Added by qt3to4:
#include <QResizeEvent>
#include <QShowEvent>
#include <QHideEvent>
#include <QCloseEvent>
#include "util.h"
#include "wutil.h"
#include "logic.h"
#include "roomgen.h"
#include "resources.h"
//find string in the editor window
class FindEdit : public QWidget
{
Q_OBJECT
public:
FindEdit( QWidget *parent=0, const char *name=0, Q3MultiLineEdit *edit=0,QStatusBar *s=0);
QStatusBar *status;
QPushButton *find_first,*find_next,*cancel;
QRadioButton *up,*down,*start,*current;
QCheckBox *match_whole,*match_case;
QLineEdit *find_field;
Q3MultiLineEdit *editor;
int curline;
public slots:
void find_first_cb();
void find_next_cb();
void cancel_cb();
};
class LogicSyntaxHL;
//Logic editor
class LogEdit : public QWidget
{
Q_OBJECT
public:
LogEdit( QWidget *parent=0, const char *name=0,int winnum=0,ResourcesWin *res=0, bool readonly=false );
Q3MultiLineEdit *editor;
FindEdit *findedit;
ResourcesWin *resources_win;
QStatusBar *status;
RoomGen *roomgen;
Logic *logic;
LogicSyntaxHL *syntax_hl;
string filename;
unsigned int maxcol;
int open();
int open(int ResNum);
public slots:
void new_room();
void read_logic();
void save_logic();
void save_as();
int compile_logic();
int compile_all_logic();
void compile_and_run();
void change_logic_number();
void delete_logic();
void clear_all();
void find_cb();
void find_again();
void goto_cb();
void context_help();
void command_help();
void update_line_num( int para, int pos );
protected:
int LogicNum;
int winnum;
bool changed;
int open(char *filename);
void save(char *filename);
void deinit();
void delete_file(int num);
void getmaxcol();
void resizeEvent( QResizeEvent * );
void closeEvent( QCloseEvent *e );
void showEvent( QShowEvent * );
void hideEvent( QHideEvent * );
};
//a simple text editor
class TextEdit : public QWidget
{
Q_OBJECT
public:
TextEdit( QWidget *parent=0, const char *name=0,int winnum=0);
Q3MultiLineEdit *editor;
FindEdit *findedit;
QStatusBar *status;
string filename;
int open(char *filename);
void save(const char *filename);
public slots:
void new_text();
void clear_all();
void open();
void save();
void save_as();
void find_cb();
void find_again();
protected:
string OutputText;
int winnum;
bool changed;
void closeEvent( QCloseEvent *e );
void showEvent( QShowEvent * );
void hideEvent( QHideEvent * );
void deinit();
};
#endif

37
src/logic.cpp Normal file
View File

@@ -0,0 +1,37 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include "logic.h"
#include <stdio.h>
#include <stdlib.h>
Logic::Logic()
{
wordlist = new WordList();
objlist = new ObjList();
maxcol=80;
OutputText = "";
}

91
src/logic.h Normal file
View File

@@ -0,0 +1,91 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef LOGIC_H
#define LOGIC_H
#include "words.h"
#include "object.h"
#include "agicommands.h"
#include "game.h"
#define MaxBlockDepth 12
#define MaxLabels 255
#define MaxDefines 255
#define MaxMessages 256
#define MaxGotos 255
//Logic class used both for decode and compile
class Logic
{
public:
Logic();
WordList *wordlist;
ObjList *objlist;
string OutputText; //result of the decoding
string ErrorList; //compilation error messages
unsigned int maxcol; //max number of columns in window - used in formatting 'print' strings
int compile();
int decode(int resnum);
private:
void ShowError(int Line, string ErrorMsg);
void DisplayMessages();
void ReadMessages();
int FindLabels_ReadIfs();
void AddBlockEnds();
int FindLabels();
void AddArg(byte Arg, byte ArgType);
void AddSpecialSyntaxCommand();
void AddSpecialIFSyntaxCommand();
void ReadIfs();
string ReadString(string::size_type *pos, string& str);
int RemoveComments(TStringList Lines);
int AddIncludes();
int ReadDefines();
int ReadPredefinedMessages();
int ReadLabels();
void NextLine();
void SkipSpaces();
byte MessageNum(string TheMessage);
byte AddMessage(string TheMessage);
string ReplaceDefine(string InText);
void ReadArgText();
int ReadArgValue();
int Val(string str);
void ReadArgs(bool CommandIsIf, byte CmdNum);
string ReadText();
string ReadPlainText();
string ReadExprText();
void ReadCommandName();
byte FindCommandNum(bool CommandIsIf,string CmdName);
bool AddSpecialIFSyntax();
bool AddSpecialSyntax();
int LabelNum(string LabelName);
bool LabelAtStartOfLine(string LabelName);
void WriteMessageSection();
int CompileCommands();
};
extern char tmp[];
#endif

168
src/logo.xpm Normal file
View File

@@ -0,0 +1,168 @@
/* XPM */
static const char *logo[] = {
/* columns rows colors chars-per-pixel */
"320 148 14 1",
" c black",
". c #505050",
"X c #0000A0",
"o c #5050FF",
"O c #00A000",
"+ c #50FF50",
"@ c #00A0A0",
"# c #50FFFF",
"$ c #A00000",
"% c #A05000",
"& c #FF5050",
"* c #FFFF50",
"= c #A0A0A0",
"- c gray100",
/* pixels */
"--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
"--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
"--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
"--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
"--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
"---------------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
"------------------------ OOOOOO ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
"---------------------- OOOOOOOOOOOOOO ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
"-------------------- OOOOOOOOOOOOOOOOOO --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
"-------------------- OOOOOOOOOOOOOOOOOOOO ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
"------------------ OOOOOOOOOOOOOOOOOOOOOOOO ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
"---------------- OOOOOOOOOOOOOOOOOOOOOOOOOO ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
"---------------- OOOOOOOOOO OOOOOOOOOO --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
"-------------- OOOOOOOOOO -------- OOOOOOOO --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
"-------------- OOOOOOOO ---------- OOOOOOOO --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
"-------------- OOOOOO -------------- OOOOOO --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
"------------ OOOOOOOO -------------- OOOOOOOO ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
"------------ OOOOOO ------------------ OOOOOO ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
"------------ OOOOOO ------------ ---- OOOOOO ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
"------------ OOOO ------------ ------ OOOO ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
"------------ OOOO ------------ OO ---- OOOO ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
"---------- OOOOOO ---------- OOOO ---- OOOOOO ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
"---------- OOOO ------------ OOOOOO -- OOOOOO ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
"---------- OOOO ---------- OOOOOOOO -- OOOOOO ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
"---------- OOOO ---------- OOOOOOOO ---- OOOO ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
"---------- OOOO -------- OOOOOOOO ------ OOOO ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
"---------- OOOO -------- OOOOOOOO ------ OOOO ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
"---------- OOOO ------ OOOOOOOOOO ------ OOOO ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
"---------- OOOO ------ OOOOOOOOOO ------ OOOO ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
"---------- OOOO ---- OOOOOOOOOOOOOO ---- OOOO ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
"---------- OOOO ---- OOOOOOOOOOOOOO ---- OOOO ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
"---------- OOOOOO -- OOOOOOOOOOOOOOOO -- OOOO ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
"---------- OOOOOO ---- OOOO OOOOOOOO OOOOOO ---------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
"------------ OOOO ---- OO -- OOOOOOOO OOOO ------------ ---------------------------------------- XXXXXXXXXX ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
"------------ OOOOOO ---- -- OOOOOOOO OOOO ------------ XXXXXXXXXXXXXXXX@@ -------------------------------------- XXXXXXXXXXXXXX@@@@@@@@ ------------------------ --------------------------------------------------------------------------------------------------------------------------------",
"------------ OOOOOO ---- ------ OOOOOOOOOOOO ------------ XXXXXXXXXXXXXXXX@@ ---------------------------------- XXXXXXXXXXXXXXXXXXXXXXXX@@ ---------------------- XXXXXXXXXXXXXX@@ --------------------------------------------------------------------------------------------------------------------------------",
"------------ OOOOOOOO ---------- OOOOOOOOOO -------------- XXXXXXXXXXXXXXXX@@XX ------------------------------ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX@@ -------------------- XXXXXXXXXXXXXX@@ --------------------------------------------------------------------------------------------------------------------------------",
"------------ OOOOOOOO ------------ OOOOOOOO ------------ XXXXXXXXXXXXXXXXXXXX@@ ---------------------------- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX@@ -------------------- XXXXXXXXXXXXXX@@ --------------------------------------------------------------------------------------------------------------------------------",
"-------------- OOOOOOOO ---------- OOOOOOOO ------------ XXXXXXXXXXXXXXXXXXXX@@ -------------------------- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX@@ ------------------ XXXXXXXXXXXXXX@@ ------------------------------------------------------------------------------------------&&------------------------------------",
"-------------- OOOOOOOOOO ---- OOOOOOOOOOOO ---------- XXXXXXXXXXXXXXXXXXXX@@ -------------------------- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX@@ ---------------- XXXXXXXXXXXXXX@@ ----------------------------------------------------------------------------------------&&----------------$$--------------------",
"---------------- OOOOOOOOOOOO OOOOOOOOOOOO ---------- XXXXXXXXXXXXXXXXXXXX@@ ------------------------ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX@@ ---------------- XXXXXXXXXXXXXX@@ ----------------------------------------------------------------------------------------&&----------------$$--------------------",
"---------------- OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO -------- XXXXXXXXXXXXXXXXXXXX@@ ------------------------ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX@@ -------------- XXXXXXXXXXXXXX@@ --------------------------------------------------------------------------------------&&$$----------------$$$$------------------",
"------------------ OOOOOOOOOOOOOOOOOOOOOO OOOOOO -------- XXXXXXXXXXXXXXXXXXXXXX@@ -------------------- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX@@ -------------- XXXXXXXXXXXXXX@@ -------------------------------- ----------------------------------------------&&$$$$--$$ ----------$$------------------",
"-------------------- OOOOOOOOOOOOOOOOOO OOOO -------- XXXXXXXXXXXXXXXXXXXXXXXX@@ -------------------- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX@@ -------------- XXXXXXXXXXXXXX@@ ------------------------------ --------------------------------------------&&$$$$$$$$$$ --------$$------------------",
"-------------------- OOOOOOOOOOOOOOOOOO -- OO -------- XXXXXXXXXXXXXXXXXXXXXXXX@@ ------------------ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX@@ -------------- XXXXXXXXXXXXXX@@ ------------------------------ --------------------------------------------&&$$$$$$$$$$$$ ------$$ ----------------",
"---------------------- OOOOOOOOOOOO ---- ---------- XXXXXXXXXXXXXXXXXXXXXXXX@@ ------------------ XXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXX@@ ------------ XXXXXXXXXXXXXX@@ ---------------------------- ------------------------------------------&&$$$$$$$$$$$$$$ ----&&$$ ----------------",
"------------------------ ---------- ---------- XXXXXXXXXXXXXXXXXXXXXXXX@@ ------------------ XXXXXXXXXXXXXXXX@@XX -- XXXXXXXXXXXXXXXXXX@@ ------------ XXXXXXXXXXXXXX@@ ---------------------------- ------------------------------------------&&$$$$$$$$$$$$$$ &&$$$$ ----------------",
"---------------------------------------------------------- XXXXXXXXXXXXXXXXXXXXXXXXXX@@ ---------------- XXXXXXXXXXXXXX@@ ---------- XXXXXXXXXXXXXXXX@@ ------------ XXXXXXXXXXXXXX@@ -------------------------- ------------------------------------------&&$$==$$$$$$$$$$$$&&$$$$$$ ----------------",
"---------------------------------------------------------- XXXXXXXXXXXXXXXXXXXXXXXXXX@@ -------------- XXXXXXXXXXXXXXXX@@ -------------- XXXXXXXXXXXXXX@@ ------------ XXXXXXXXXXXXXX@@ -------------------------- ----------------------------------------$$$$==$$==$$$$$$$$$$$$$$$$ ----------------",
"-------------------------------------------------------- XXXXXXXXXXXXXXXXXXXXXXXXXXXX@@ -------------- XXXXXXXXXXXXXX@@ ---------------- XXXXXXXXXX@@@@ ------------ XXXXXXXXXXXXXX@@ -------------------------- ----------------------------------------$$----======$$$$$$$$$$$$$$ ----------------",
"-------------------------------------------------------- XXXXXXXXXXXX@@ XXXXXXXXXXXX@@ -------------- XXXXXXXXXXXXXX@@ ------------------ XXXX@@@@ ---------------- XXXXXXXXXXXXXX@@ -------------------------- -- -- ----------------------------------------$$--==----==&&$$$$$$$$$$ ------------------",
"-------------------------------------------------------- XXXXXXXXXXXX@@ XXXXXXXXXXXX@@ -------------- XXXXXXXXXXXX@@ -------------------- @@@@ -------------------- XXXXXXXXXXXXXX@@ -------------------------- ---- ------ ----------------------------------------==--==----==&&$$$$$$$$$$ ------------------",
"-------------------------------------------------------- XXXXXXXXXXXX@@ XXXXXXXXXXXXXX@@ ------------ XXXXXXXXXXXX@@ ---------------------- ------------------------ XXXXXXXXXXXXXX@@ -------------------------- -- --..-- ----------------------------------------== == --==&&$$$$$$$$ --------------------",
"-------------------------------------------------------- XXXXXXXXXXXX@@ XXXXXXXXXXXXXX@@ ------------ XXXXXXXXXXXX@@ -------------------------------------------------- XXXXXXXXXXXXXX@@ -------------------------- -- ---- -- ----------------------------------------== -- --==&&$$$$$$ ----------------------",
"-------------------------------------------------------- XXXXXXXXXX@@ -- XXXXXXXXXXXX@@ ------------ XXXXXXXXXXXX@@ -------------------------------------------------- XXXXXXXXXXXXXX@@ -------------------------- --..%%%%..-- ----------------------------------------$$ --==&&$$$$$$ ----------------------",
"------------------------------------------------------ XXXXXXXXXXXX@@ -- XXXXXXXXXXXX@@ ------------ XXXXXXXXXXXX@@ -------------------------------------------------- XXXXXXXXXXXXXX@@ -------------------------- --%%****%%-- --------------------------------------&&&&== --==$$$$$$ ----------------------",
"------------------------------------------------------ XXXXXXXXXXXX@@ -- XXXXXXXXXXXX@@ ---------- XXXXXXXXXXXXXX@@ -------------------------------------------------- XXXXXXXXXXXXXX@@ --------------------------..%%********%% --------------------------------------&&$$$$.. --==$$$$$$ ----------------------",
"------------------------------------------------------ XXXXXXXXXXXX@@ -- XXXXXXXXXXXX@@ ---------- XXXXXXXXXXXXXX@@ -------------------------------------------------- XXXXXXXXXXXXXX@@ -------------------------- **********%% --------------------------------------&&$$$$&&..==$$$$$$$$ ----------------------",
"------------------------------------------------------ XXXXXXXXXXXX@@ -- XXXXXXXXXXXXXX@@ -------- XXXXXXXXXXXXXX@@ -------------------------------------------------- XXXXXXXXXXXXXX@@ -------------------------- %%%%****%%%% ----------------------------------**--&&$$&&$$..$$$$$$$$$$ ----------------------",
"------------------------------------------------------ XXXXXXXXXXXX@@ -- XXXXXXXXXXXXXX@@ -------- XXXXXXXXXXXX@@ ---------------------------------------------------- XXXXXXXXXXXXXX@@ -------------------------- %%%%%%%%%%%% ----------------------------------**-- $$$$$$..$$$$$$$$ ------------------------",
"------------------------------------------------------ XXXXXXXXXXXX@@ -- XXXXXXXXXXXXXX@@ -------- XXXXXXXXXXXX@@ ------------ ---------- XXXXXXXXXXXXXX@@ -------------------------- ==%%%%%%%%-- ------------------------------**--%%---- $$$$$$$$$$$$$$ ------------------------",
"---------------------------------------------------- XXXXXXXXXXXX@@ ------ XXXXXXXXXXXX@@ -------- XXXXXXXXXXXX@@ ------------ XXXXXXXXXXXXXXXXXXXXXXXX@@ ---------- XXXXXXXXXXXXXX@@ -------------------------- ====%%%%==-- ----------------------------%%****%%-- $$$$$$$$ $$$$ --------------------------",
"---------------------------------------------------- XXXXXXXXXXXX@@ ------ XXXXXXXXXXXX@@ -------- XXXXXXXXXXXX@@ ------------ XXXXXXXXXXXXXXXXXXXXXXXX@@ ---------- XXXXXXXXXXXXXX@@ -------------------------- --======---- ----------------------------%%****%%---- $$$$.. $$$$ --------------------------",
"---------------------------------------------------- XXXXXXXXXXXX@@ ------ XXXXXXXXXXXXXX@@ ------ XXXXXXXXXXXX@@ ------------ XXXXXXXXXXXXXXXXXXXXXXXX@@ ---------- XXXXXXXXXXXXXX@@ ------------------------== ----==-------- ----------------------------%%**%%------$$.. $$$$----------------------------",
"---------------------------------------------------- XXXXXXXXXXXX@@ ------ XXXXXXXXXXXXXX@@ ------ XXXXXXXXXXXX@@ ------------ XXXXXXXXXXXXXXXXXXXXXXXX@@ ---------- XXXXXXXXXXXXXX@@ ------------------------== -------------- ------------------------%%********$$$$---- $$$$$$$$----------------------------",
"---------------------------------------------------- XXXXXXXXXXXX@@ ------ XXXXXXXXXXXXXX@@ ------ XXXXXXXXXXXX@@ ------------ XXXXXXXXXXXXXXXXXXXXXXXX@@ ---------- XXXXXXXXXXXXXX@@ ------------------------.. -------------- ------------------------%%%%****$$$$----$$$$$$$$$$----------------------------",
"---------------------------------------------------- XXXXXXXXXXXX@@ ------ XXXXXXXXXXXXXX@@ ------ XXXXXXXXXXXX@@ ------------ XXXXXXXXXXXXXXXXXXXXXXXX@@ ---------- XXXXXXXXXXXXXX@@ ------------------------.. ------------== ----------------------------%%$$$$$$ --$$$$$$$$$$----------------------------",
"-------------------------------------------------- XXXXXXXXXXXXXX@@ ------ XXXXXXXXXXXXXX@@ ------ XXXXXXXXXXXX@@ ------------ XXXXXXXXXXXXXXXXXXXXXXXX@@ ---------- XXXXXXXXXXXXXX@@ ------------------------ ..----------====.. ------------------------------$$$$$$ $$$$$$$$&&$$$$--------------------------",
"-------------------------------------------------- XXXXXXXXXXXX@@ ---------- XXXXXXXXXXXXXX@@ ---- XXXXXXXXXXXX@@ ------------ XXXXXXXXXXXXXXXXXXXXXXXX@@ ---------- XXXXXXXXXXXXXX@@ ------------------------ ..==----------==.. ----------------------------$$$$ $$$$$$&&$$$$$$--------------------------",
"-------------------------------------------------- XXXXXXXXXXXX@@ ---------- XXXXXXXXXXXXXX@@ ---- XXXXXXXXXXXX@@ ------------ XXXXXXXXXXXXXXXXXXXXXXXX@@ ---------- XXXXXXXXXXXXXX@@ ------------------------ ====----------==.. ------------------------------$$ ....&&$$$$$$..--------------------------",
"-------------------------------------------------- XXXXXXXXXXXX@@ ---------- XXXXXXXXXXXXXX@@ ---- XXXXXXXXXXXX@@ ------------ XXXXXXXXXXXXXXXXXXXXXXXX@@ ---------- XXXXXXXXXXXXXX@@ ---------------------- ==--------------.. ------------------------------$$$$..&&$$..$$$$$$..--------------------------",
"-------------------------------------------------- XXXXXXXXXXXX@@ XXXXXXXXXXXXXX@@ ---- XXXXXXXXXXXXXX@@ ---------- @@@@@@@@@@@@XXXXXXXXXXXX@@ ---------- XXXXXXXXXXXXXX@@ ---------------------- ----------------== --------------------------------$$&&$$$$$$$$$$....--------------------------",
"-------------------------------------------------- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX@@ ---- XXXXXXXXXXXXXX@@ OO-------- XXXXXXXXXXXX@@ OO-------- XXXXXXXXXXXXXX@@ ---------------------- -------------------- ----------------------------------&&$$$$$$$$.... --------------------------",
"----------------------------------------OO------ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX@@ ---- XXXXXXXXXXXXXX@@ OOOO----------OO++++++ XXXXXXXXXXXX@@ OOOO------ XXXXXXXXXXXXXX@@ ---------------------- -------------------- ----------------------------------&&$$$$$$.... --------------------------",
"--------------------------------------OOOOOO---- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX@@ -- XXXXXXXXXXXXXX@@ OOOOOO----OOOO++++++++ XXXXXXXXXXXX@@ OOOOOO---- XXXXXXXXXXXXXX@@ --OOOOOO------------ ==-------------------- ----------------------------------.......... --------------------------",
"------------------------------------OO++OOOOOO-- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX@@ -- XXXXXXXXXXXXXX@@ OOOOOOOOOO++++++++++++ XXXXXXXXXXXX@@ OOOOOOOO-- XXXXXXXXXXXXXX@@ OO++OOOOOOOOOOOO---- ..-------------------- ----------------------------------&&...... $$ --------------------------",
"----------------------------------OO++++OOOOOOOO XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX@@ --OO XXXXXXXXXXXX@@ OOOOOOOOOO++++++++++++ XXXXXXXXXXXX@@ OOOOOOOO-- XXXXXXXXXXXXXX@@ ++++OOOOOOOOOOOOOOOO -------------------- ----------------------------------&&$$ **$$$$--------------------------",
"--------------------------------OO++++++OOOOOOOO XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX@@ OO++ XXXXXXXXXXXXXX@@ OOOOOOOO++++++++++++ XXXXXXXXXXXX@@ OOOOOOOOOO XXXXXXXXXXXXXX@@ ++++++OOOOOOOOOOOOOO -------------------- ----------------------------------$$$$ **$$$$--------------------------",
"------------------------------OO++++++++OOOOOOOO XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX@@++++ XXXXXXXXXXXXXX@@ OOOOOOOOOO++++++++++ XXXXXXXXXXXX@@ OOOOOOOOOO XXXXXXXXXXXXXX@@ ++++++OOOOOOOOOOOOOO -------------------- ----------------++----------------$$$$$$ $$%%**$$--------------------------",
"------------------------------OO++++OO++++OOOO XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX@@ ++ XXXXXXXXXXXXXXXX@@ OOOOOOOO++++++++++ XXXXXXXXXXXX@@ OOOOOOOOOO XXXXXXXXXXXXXX@@ ++++++OOOOOOOOOOOOOO -------------------- OO------------++--++OO--------------$$$$$$$$$$**$$--------------------------",
"----------------------------OO++++++++++++OOOO XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX@@ ++ XXXXXXXXXXXXXXXX@@ ++++OOOO++++++++ XXXXXXXXXXXXXX@@ ++OOOOOOOO XXXXXXXXXXXXXX@@ ++++++++OOOOOOOOOOOO%% -------------------- ++OO--------++--OOOO++OO------------$$$$$$$$$$$$ --------------OO----------",
"--------------------OOOO----OO++++++OO++++OOOO XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX@@ ++++ XXXXXXXXXXXXXXXX@@ ++++++++++++ XXXXXXXXXXXXXX@@ ++++OOOOOO XXXXXXXXXXXXXX@@ ++++++++++OOOOOOOO%%** --------------**** ++++OO----++--OOOOOOOOOO--------------$$$$$$++ --------OOOOOOOOOO------",
"----------------OOOOOOOO--OO++++++OO++++++++OO XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX@@ ++++ XXXXXXXXXXXXXXXXXX ++++++ XXXXXXXXXXXXXXXXXX@@ ++++OOOOOO XXXXXXXXXXXXXX@@ ++++++++OO++OOOOOO%%**** --------------** ++++++OO++OOOO++OOOOOOOOOO------------++OOOO++OO ------OO++OOOOOOOO----",
"------------OOOOOOOOOOOOOOOO++++++++++++++++++ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX@@ ++++ XXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXX@@ ++++OOOOOO XXXXXXXXXXXXXX@@ ++++++++++++OOOO%%****** --------------** %%++++++OOOO++++++++OOOOOOOOOO----------++OOOOOOOO.... --OO++++OOOOOOOO----",
"----------OOOOOOOOOOOOOOOO++++++++++++++++++++ XXXXXXXXXXXXXX@@@@@@@@@@@@@@@@@@@@@@@@XXXXXXXXXXXXXX@@ ++++ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX@@ ++++OOOOOO XXXXXXXXXXXXXX@@ ++++++++++++OOOO%%******** ------------** ****%%++++OOOOOO++++OOOOOOOOOOOO--======OOOOOO++OOOOOO--.... OO++++++OOOOOO----",
"----------OO++++OOOOOOOOOOOO++++++++++++++++ XXXXXXXXXXXXXXXX@@ XXXXXXXXXXXXXX@@ ++++ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX@@ ++++OOOOOO XXXXXXXXXXXXXX@@ ++++++OO++OOOOOO%%******** ----------%% ******%%++++OOOOOO++++++OOOOOOOO====OO..OOOO++++OOOOOOOO------ ++OOOOOOOO--",
"--------OO++++++++++OOOOOOOO++++++++++++++++ XXXXXXXXXXXXXXXX@@ OO++++++++++++++++ XXXXXXXXXXXXXX@@ ++++++ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX@@ ++++++OOOOOO XXXXXXXXXXXXXX@@ ++++++++++OOOOOO%%********** --------==%% ********%%++OOOOOO++++++OOOOOOOO==OOOO..OOOO++OOOOOOOOOO....--OO.... OOOOOO--",
"--------OO++++++++++OOOOOOOOOO++++++++++++++ XXXXXXXXXXXXXXXX@@ OO++++++++++++++++ XXXXXXXXXXXXXX@@ ++++++ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX@@ ++++++++OOOOOO XXXXXXXXXXXXXX@@ ++++++++++OOOOOO%%********** ------====%%**********%%++OOOOOOOO++++++++OO==--OO..====OOOOOOOOOOOO........OO++++....$$$$OOOO--",
"------OO++++++++++++++OOOOOOOO++++++++++++++ XXXXXXXXXXXXXX@@ OOOOOO++++++++++++++++ XXXXXXXXXXXX@@ ++++++++ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX@@ ++++++++OOOOOO XXXXXXXXXXXXXX@@ ++++++++++OOOOOO%%**********%%--------==..%%**********%%++OOOOOOOO++OO++++++==........--==OOOOOO................++++++....$$OO--",
"----OO++++++++++++++++++++OOOO++++++++++++++ XXXXXXXXXXXXXX@@ OOOOOO++++OO++++++++++ XXXXXXXXXXXX@@ ++++++++ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX@@ ++++++++OOOOOOOO XXXXXXXXXXXXXX@@ ++++++++OOOOOO%%************%%------==.. %%**********%%++OOOOOOOO++++++++++..====................................&&++++..$$OOOO",
"----OO++++++++++++++++++++++++++++++++++++++ XXXXXXXXXXXXXX@@ OOOOOO++++OO++++++++++ XXXXXXXXXXXXXX@@ ++++++++ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX@@ ++++++++++OOOOOOOO XXXXXXXXXXXXXX@@ ++++++++OOOOOO%%%%**********%%--======.. %%**********%%++++OOOOOO++++++....====................................&&$$++..$$OOOOOO",
"--OO++++++++++++++++++++++++++++++++++++++ XXXXXXXXXXXXXXXX@@++++++OOOOOO++++OO++++++ XXXXXXXXXXXXXX@@ ++++++++++ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX@@ ++++++++++++OOOOOOOO XXXXXXXXXXXXXX@@ ++++++OOOOOOOO%%%%**********%%====.... %%********%%++++++OOOOOO++....================........................&&$$$$..OOOOOOOO",
"--OO++++++++++OO++++OO++++++++++++++++++++ XXXXXXXXXXXXXX@@ ++OO++++++++++++++++++++++ XXXXXXXXXXXX@@ ++++OO++++++ XXXXXXXXXXXXXXXXXXXXXXXX@@@@ ++++OO++++++++OOOOOOOO XXXXXXXXXXXXXX@@ ++++++++++OOOO%%%%%%********%% %%******%%%%++++++OOOOOO..========================..................&&$$$$.. OOOOOO",
"--OO++++++++++++++++++++++++++++++OOOO++++ @@@@@@@@@@@@@@@@ ++++++++++++OO++++++++++++ @@@@@@@@@@@@@@ ++++OO++++++++ @@@@@@@@@@@@@@@@@@@@@@ ++++++++++++++++++OO++++ XXXXXXXXXXXXXX@@ ++++++OO++OOOOOO%%%%******%%%% %%******%%....++++OOOO..==============================............&&$$$$$$ OOOOOO",
"--OO++++++++++OO++OO++++++++++++OOOOOO++++ ++++++++++++++++++++++++++ ++++++OO++++++++ ++++++OO++++OO++++OOOO++++++ @@@@@@@@@@@@@@@@ ++++++++OO++OOOO..%%%%****%%%%==..........%%%%**%%.... ++++....====....============....========.................... OOOOOO",
"--OO++++++++++++++++++++++++++++OOOOOOOO++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++OO++++++++++++++++++++++++++++++++++++++++++++OO++++++++OO++++++ ++++OO++++++OO..====%%%%%%%%====..........%%%%%%%%.... ..==......==..================....======.................... OOOO",
"OO++++++++++++++OO++++++++++++++OOOOOOOO++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++OO++++++++++++++++++++++++++++++++++++++++++OO++++++++++++++++++++OOOOOOOOOOOO++++++OO++++++++..======%%%%%%==========......%%%%........ ========..========================..====.................... OOOO",
"OO++++++++++++++++++++++++++++OOOOOOOO++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++OOOOOOOOOO++++++++OO++++++..========================................ ======....========================..====.................. OOOO",
"OO++++++++++++++++++++++++++++OOOOOOOO++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++OOOO++++++++++++++++..========================................ ========..========================......==.................. OOOO",
"OO++++++++++++++++++++++++++++OOOOOO++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++..============================................ ============================....======.................... OOOO",
"++++++++++++++++++++++%%%%%%%%%%%%%%++++++++++ &&&&&& ++++++++ ++ ++++++++ ++++ ++++++++++++ ++++++++++++ ++++++++++++++++..==============================.............. ==========================================................ OOOO",
"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% &&&&&&&&&&&& %%++++ &&&&&&&&&&&&&&&&&&&&&& ++ &&&&&& ++++++++ &&&&&& ++++ &&&&&&&&&&&&&& ++++++++++ &&&&&& ++++++++++ &&&&&&&&&&&& ++++++++++++++..================================............ ========================================................ OO",
"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% &&&&&&&&&&&&&& %%%%%% &&&&&&&&&&&&&&&&&&&&&& ++ &&&&&& ++++++++ &&&&&& ++++ &&&&&&&&&&&&&&&& ++++++++ &&&&&& ++++++++ &&&&&&&&&&&&&&&& ++++++%%%%%%..================================............ ==========================================................ OO",
"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% &&&&&&&&&&&&&&&& %%%% &&&&&&&&&&&&&&&&&&&&&& %% &&&&&& %%%%++++ &&&&&& ++++ &&&&&&&&&&&&&&&&&& ++++++ &&&&&& ++++++++ &&&&&&&&&&&&&&&& %%%%%%%%%%%%..======================....====..====.......... ==========================================................ OO",
"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% &&&&&& &&&&&& %%%% &&&&&&&&&&&&&&&&&&&&&& %% &&&&&& %%%%%%%% &&&&&& %%++ &&&&&&&&&&&&&&&&&&&& ++++ &&&&&& ++%%%% &&&&&&&&&&&&&&&&&&&& %%%%%%%%%%..==========================....======.......... ============================================.............. OO",
"%%%%%%%%%%%%%%%%%%%%%%%%%%********%%%%%% &&&& %%%%%% &&&& %%%% &&&&&&&&&&&&&&&&&&&&&& %% &&&&&& %%%%%%%% &&&&&& %%%% &&&&&& &&&&&&&& %%%% &&&&&& %%%%%% &&&&&& &&&&&& %%%%%%%%%%..============================..========........ ==========================================.............. OO",
"%%%%%%%%%%****************************** &&&& %%%%%% %%%% &&&&&& %% &&&&&& %%%%%%%% &&&&&& %%%% &&&&&& %%%% &&&&&& %%%% &&&&&& %%%%%% &&&& %%%%%%%% &&&& %%%%%%%%..============================..==========.......... ============================================............ oo",
"**************************************** &&&&&& %%%%%%%%%%%%%%%%%%%%%%%% &&&&&& %%%%%%%%%% &&&&&& %%%%%%%% &&&&&& **%% &&&&&& %%%% &&&&&& %%%% &&&&&& %%**** &&&& %%%%%%%% &&&& %%%%****..============================..============........ ============================================............ oo",
"**************************************** &&&&&& %%%%%%******%%%% &&&&&& %%%%%%%%%% &&&&&& %%%%**** &&&&&& **** &&&&&& %%%% &&&&&& %%** &&&&&& ****** &&&& ******** &&&& ********..============================..============........ ============================================............ oo",
"****************************************** &&&&&&&&&&&&&& ************** &&&&&& ********** &&&&&& ******** &&&&&& **** &&&&&& **** &&&&&& **** &&&&&& ****** &&&& ******** &&&& ********..==========================================........ ============================================.............. oo",
"****************************************** &&&&&&&&&&&&&&&& ************ &&&&&& ********** &&&&&& ******** &&&&&& **** &&&&&& **** &&&&&& **** &&&&&& ****** &&&& ******** &&&& ********..============================================...... ==============================================............ oo",
"******************************************** &&&&&&&&&&&& ************ &&&&&& ********** &&&&&& ******** &&&&&& **** &&&&&& **** &&&&&& **** &&&&&& ****** &&&& ******** &&&& ********..============================================........ ==============================================............ oo",
"oooooooooooooooooooooooooooooooooooooooooooooooo &&&&&&&&&& oooooooooo &&&&&& oooooooooo &&&&&& oooooooo &&&&&& oooo &&&&&& oooo &&&&&& oooo &&&&&& oooooo &&&& oooooooo &&&& oooooooooo============================================........ ==============================================............ oo",
"oooooooooooooooooooooooooooooooooooooooooooooooooooo &&&&&&&& oooooooooo &&&&&& oooooooooo &&&&&& oooooooo &&&&&& oooo &&&&&& oooo &&&&&& oooo &&&&&& oooooo &&&& oooooooo &&&& oooooooooooo==========================================........ ==============================================............ oo",
"oooooooooooooooooooooooooooooooooooooo oooooo &&&&&& oooooooooo &&&&&& oooooooooo &&&&&& oooooooo &&&&&& oooo &&&&&& oooo &&&&&& oooo &&&&&& oooooo &&&& oooooooo &&&& oooooooooooooooo======================================........ ==============================================............ oo",
"oooooooooooooooooooooooooooooooooooooo &&&&&& oooooo &&&&&& oooooooooo &&&&&& oooooooooo &&&&&& oooooooo &&&&&& oooo &&&&&& oooo &&&&&& oooo &&&&&& oooooo &&&& oooooooo &&&& oooooooo##oooooooo====================================........ ==============================================............ oo",
"oooooooooooooooooooooooooooooooooooooo &&&&&& oooooo &&&&&& oooooooooo &&&&&& oooooooooo &&&&&&&& &&&&&&&& oooo &&&&&& &&&&&&&& oooo &&&&&& oooooo &&&&&& &&&&&& oooooooooo##oooooooo====================================...... ==============================================............ oo",
"oooooooooooooooooooooooooooooooooooooo &&&&&&&& oooo &&&&&& oooooooooo &&&&&& oooooooooo &&&&&&&&&&&&&&&&&&&&&& oooooo &&&&&&&&&&&&&&&&&&&& oooo &&&&&& oooooo &&&&&&&&&&&&&&&&&&&& oooooooooooo##oooooooooo====================oooo========oooooooooooooo========================================.......... oooo",
"oooooooooooooooooooooooooooooooooooooooo &&&&&&&& &&&&&& oooooooooooo &&&&&& oooooooooooo &&&&&&&&&&&&&&&&&&&& oooooo &&&&&&&&&&&&&&&&&& oooooo &&&&&& oooooooo &&&&&&&&&&&&&&&& oooooooooooooooo##oooooooooo================oooooooooooooooooooooooooooooooooooooooo==============================........ oooo",
"oooooooooooooooooooooooooooooooooooooooo &&&&&&&&&&&&&&&&&& oooooooooooo &&&&&& oooooooooooo &&&&&&&&&&&&&&&&&& oooooooo &&&&&&&&&&&&&&&&&& oooooo &&&&&& oooooooo &&&&&&&&&&&&&&&& oooooooooooooooooo##oooooooooooo============oooooooooooooooooooooooooooooooooooooooooooo==========================........ oooo",
"oooooooooooooooooooooooooooooooooooooooooo &&&&&&&&&&&&&& oooooooooooooo &&&&&& oooooooooooooo &&&&&&&&&&&&&&&& oooooooo &&&&&&&&&&&&&& oooooooo &&&&&& oooooooooo &&&&&&&&&&&& oooooooooooooooooooooo####oooooooooooooooooooooooooooo##########oooooooooooooooooooooo##oooooo======================........ oooo",
"oooooooooooooooooooooooooooooooooooooo##oooo oooooooooooooooo oooooooooooooooo oooooooooo oooooooooooo oooooooooooo oooooooooooooooooooooooooooo####oooooooooooooooooooo####oooooooooooooooooooooooooooooooooo##oooooooo==================........ oo##",
"oooooooooooooooooooooooooooooooooooooooo##oooooooooooooooooooooooo##oooooooooooooooooo##oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo##oooo########oooooooooooo####oooooooooooooo##oooooooooooooooooooooooo########oooooooo##oooooooooooooooooooooooooooooooooo##oo",
"oooooooooooooooooooooooooooooooooooooooooo##oooooooooooooooooooo##oooooooooooooooooo##oooooo##oooooooooooooooooooooooooooooooooooooooooooooooooooooo########oooooooooooooooooooooooooooooooooooo##oooo##oooooooooooooooooooooooooooooooooo####oooooooooooooooo##########oooooooo######oooo##oooooooooooooooooooooooooooooo##oooo",
"oooooooooooooooooooooooooooooooooooooooooooo##############oooooo##oooo##oooooo######oooooooooo####oooooooooooooooooooo##########oooooooooooooo######oooooooo######oooooooo######oooooooooooooo##oooooo##oooooooooooooooo######oooooooo####oooooooooooooo######oooooooooooooooooooooooo####oo####oooooooooooooooooooooooo##oooooo",
"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo##oooooooo######oooooooooooooooooooo########oooooooo####oooooooooooooooo########oooooooooooooooooooooooo####oooooooooooooooooooo##oooo##oooooooooooooooooooooooo########oooooooooooooooooooooooooooooooooooooooooooooooooooooooooo########oooooooooo######oooooooo",
"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo##oooooooooooooooooooooooooooooooooooooooooo########oooooooooooooo######oooooooooooooooooooooooooooo####oooooooooooooooooooooo##oooo##oooooooooooooooooooooooooooooooooooooooooooooo####oooooooooooooooooo######oooooooooooooooooooooooooo##########oooooooooooooo",
"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooo####oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo####oooooooooooooooooooooooooooooooo##oooooooooooooooooooooo####oooooooooooooooooooooooooooooooooooooooooooooooo######oooo####oooooooooo####oooooo####oooooooooooooooooooooooooooooooooooooooooooooo",
"oooooooooooooooooooooooooooooooooooooooooooo##############oooooooooooooooooooooooooooo########oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo############oooooooooooooooooooooooooooooooooooooooooooooooo####oooooooooooooo##oooooooooooooooooooooo####oooooooooooooooooooooooooooooooooooooooooo",
"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo####oooooo####oooooooo####oooooooooooooooooooooooooooooooooooooooooooooooooo##########oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo##oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo######oooooooooooooooooooooooooo##########oooooooooo######oooooooooooooooooooo####oooooooooo########oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo####oooooooooooooooooooooooooooooooooooooooooooooo######oooooo####oooooooooooooo##oooooooooooooooooooooo##oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo####oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
"--oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo--",
"------oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo------",
"--------oooooooooo------------oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo--------------------------oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo----------------------oooooooooooooooooooooooo----------------",
"------------------------------------oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo------------------------------------------------------------------oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo--------------------------------------------------------------------------",
"----------------------------------------------------oooooooooooooooooooooooooooooooooooooooooooooooo------------------------------------------------------------------------------------------oooooooooooooooooooooooooooooo----------------------------------------------------------------------------------------------------",
"--------------------------------------------------------------------------oooooooooooooooo--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
"--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
"--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
"--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
};

80
src/main.cpp Normal file
View File

@@ -0,0 +1,80 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <cstdlib>
#include <stdio.h>
#include <qapplication.h>
#include <q3mainwindow.h>
#include "menu.h"
#include "game.h"
QApplication *app;
char tmp[MAX_TMP]; //global temporary buffer
static char help[]=
"QT AGI Studio v1.1.\n\
A Sierra On-Line(tm) adventure game creator and editor.\n\
\n\
Usage: agistudio [switches] \n\
\n\
where [switches] are optionally:\n\
\n\
-dir GAMEDIR : open an existing game in GAMEDIR\n\
-help : this message\n\
\n";
//***************************************************
int main( int argc, char **argv )
{
char *gamedir=NULL;
tmp[0]=0;
for(int i=1;i<argc;i++){
if(argv[i][0] == '-'){
if(!strcmp(argv[i]+1,"dir")){
gamedir = argv[i+1];
}
else
{
if(strcmp(argv[i]+1,"help")!=0 && strcmp(argv[i]+1,"-help")!=0)
printf( "Unknown parameter.\n\n" );
printf(help);
exit(-2);
}
}
}
app = new QApplication(argc,argv);
menu = new Menu(NULL,NULL);
app->setMainWidget( menu );
game = new Game();
menu->show();
if(gamedir){
int err = game->open(gamedir);
if(!err)menu->show_resources();
}
return app->exec();
}

1173
src/menu.cpp Normal file

File diff suppressed because it is too large Load Diff

170
src/menu.h Normal file
View File

@@ -0,0 +1,170 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef MENU_H
#define MENU_H
#include <stdarg.h>
#include <string>
#include <qwidget.h>
#include <qmenubar.h>
#include <qlabel.h>
#include <qpushbutton.h>
#include <qlayout.h>
#include <q3popupmenu.h>
#include <qnamespace.h>
#include <qmessagebox.h>
#include <q3filedialog.h>
#include <qlineedit.h>
#include <q3buttongroup.h>
#include <qradiobutton.h>
#include <q3mainwindow.h>
#include <qstatusbar.h>
//Added by qt3to4:
#include <QCloseEvent>
#include "wordsedit.h"
#include "objedit.h"
#include "viewedit.h"
#include "logedit.h"
#include "picedit.h"
#include "dir.h"
#include "resources.h"
#include "helpwindow.h"
class WindowList : public QWidget
{
Q_OBJECT
public:
WindowList( QWidget *parent=0, const char *name=0 );
Q3ListBox *win;
public slots:
void draw();
void select_cb(int);
void select_ok();
void del_cb();
};
class About: public QWidget
{
Q_OBJECT
public:
About( QWidget *parent=0, const char *name=0);
};
class Menu : public Q3MainWindow
{
Q_OBJECT
public:
Menu( QWidget *parent=0, const char *name=0);
QStatusBar *status;
ResourcesWin *resources_win;
void errmes(const char *, const char *,...);
void errmes(const char *,...);
void warnmes(const char *,...);
void enable(void);
void disable(void);
void show_resources();
void enable_resources();
void disable_resources();
void inc_res(ResourcesWin *res);
void dec_res();
bool templ;
#ifdef IMGEXT
bool imgext;
void load_imgext();
#endif
public slots:
void open_game(void);
void close_game(void);
void quit_cb(void);
void run_game(void);
void settings(void);
void from_template(void);
void blank(void);
void add_resource(void);
void extract_resource(void);
void delete_resource(void);
void renumber_resource(void);
void rebuild_vol(void);
void recompile_all(void);
void new_resource_window();
void view_editor(void);
void logic_editor(void);
void text_editor(void);
void object_editor(void);
void words_editor(void);
void picture_editor(void);
void sound_player(void);
void help_contents(void);
void help_index(void);
bool help_topic( const QString& topic );
void about_it(void);
void about_qt(void);
void closeEvent( QCloseEvent *e );
int save_all(void);
void save_and_run(void);
void window_list_cb(void);
protected:
QMenuBar *menubar;
QMessageBox *err,*warn;
QPushButton *create;
Q3FileDialog *f;
QPushButton *open,*close_,*run,*view,*logic,*text,*obj,*words,*pic;
int num_res;
int n_res;
int id[24];
int max_disabled;
};
extern Menu *menu;
typedef struct {
union {
LogEdit *l;
ViewEdit *v;
WordsEdit *w;
ObjEdit *o;
PicEdit *p;
TextEdit *t;
ResourcesWin *r;
Preview *pr;
HelpWindow *h;
}w;
int type;
}WinList;
#define MAXWIN 64
extern WinList winlist[MAXWIN];
extern int get_win();
extern WindowList *window_list;
#endif //MENU_H

306
src/midi.cpp Normal file
View File

@@ -0,0 +1,306 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
* Midi support, written by Jarno Elonen <elonen@iki.fi>, 2003
* Based on SND2MIDI 1.2 by Jens Restemeier <jrestemeier@currantbun.com>
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include "global.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <qdatastream.h>
#include <qiodevice.h>
#include <q3filedialog.h>
#include <qlabel.h>
#include <q3vbox.h>
#include <qcombobox.h>
#include <q3combobox.h>
#include <qpushbutton.h>
static const char* g_gm_instrument_names[] =
{
"1. Acoustic Grand Piano",
"2. Bright Acoustic Piano",
"3. Electric Grand Piano",
"4. Honky-tonk Piano",
"5. Electric Piano 1",
"6. Electric Piano 2",
"7. Harpsichord",
"8. Clavi",
"9. Celesta",
"10. Glockenspiel",
"11. Music Box",
"12. Vibraphone",
"13. Marimba",
"14. Xylophone",
"15. Tubular Bells",
"16. Dulcimer",
"17. Drawbar Organ",
"18. Percussive Organ",
"19. Rock Organ",
"20. Church Organ",
"21. Reed Organ",
"22. Accordion",
"23. Harmonica",
"24. Tango Accordion",
"25. Acoustic Guitar (nylon)",
"26. Acoustic Guitar (steel)",
"27. Electric Guitar (jazz)",
"28. Electric Guitar (clean)",
"29. Electric Guitar (muted)",
"30. Overdriven Guitar",
"31. Distortion Guitar",
"32. Guitar harmonics",
"33. Acoustic Bass",
"34. Electric Bass (finger)",
"35. Electric Bass (pick)",
"36. Fretless Bass",
"37. Slap Bass 1",
"38. Slap Bass 2",
"39. Synth Bass 1",
"40. Synth Bass 2",
"41. Violin",
"42. Viola",
"43. Cello",
"44. Contrabass",
"45. Tremolo Strings",
"46. Pizzicato Strings",
"47. Orchestral Harp",
"48. Timpani",
"49. String Ensemble 1",
"50. String Ensemble 2",
"51. SynthStrings 1",
"52. SynthStrings 2",
"53. Choir Aahs",
"54. Voice Oohs",
"55. Synth Voice",
"56. Orchestra Hit",
"57. Trumpet",
"58. Trombone",
"59. Tuba",
"60. Muted Trumpet",
"61. French Horn",
"62. Brass Section",
"63. SynthBrass 1",
"64. SynthBrass 2",
"65. Soprano Sax",
"66. Alto Sax",
"67. Tenor Sax",
"68. Baritone Sax",
"69. Oboe",
"70. English Horn",
"71. Bassoon",
"72. Clarinet",
"73. Piccolo",
"74. Flute",
"75. Recorder",
"76. Pan Flute",
"77. Blown Bottle",
"78. Shakuhachi",
"79. Whistle",
"80. Ocarina",
"81. Lead 1 (square)",
"82. Lead 2 (sawtooth)",
"83. Lead 3 (calliope)",
"84. Lead 4 (chiff)",
"85. Lead 5 (charang)",
"86. Lead 6 (voice)",
"87. Lead 7 (fifths)",
"88. Lead 8 (bass + lead)",
"89. Pad 1 (new age)",
"90. Pad 2 (warm)",
"91. Pad 3 (polysynth)",
"92. Pad 4 (choir)",
"93. Pad 5 (bowed)",
"94. Pad 6 (metallic)",
"95. Pad 7 (halo)",
"96. Pad 8 (sweep)",
"97. FX 1 (rain)",
"98. FX 2 (soundtrack)",
"99. FX 3 (crystal)",
"100. FX 4 (atmosphere)",
"101. FX 5 (brightness)",
"102. FX 6 (goblins)",
"103. FX 7 (echoes)",
"104. FX 8 (sci-fi)",
"105. Sitar",
"106. Banjo",
"107. Shamisen",
"108. Koto",
"109. Kalimba",
"110. Bag pipe",
"111. Fiddle",
"112. Shanai",
"113. Tinkle Bell",
"114. Agogo",
"115. Steel Drums",
"116. Woodblock",
"117. Taiko Drum",
"118. Melodic Tom",
"119. Synth Drum",
"120. Reverse Cymbal",
"121. Guitar Fret Noise",
"122. Breath Noise",
"123. Seashore",
"124. Bird Tweet",
"125. Telephone Ring",
"126. Helicopter",
"127. Applause",
"128. Gunshot",
NULL
};
// Write given AGI Sound resource to given QIODevice
void writeMidi(const byte* snd, QIODevice& write_to, const unsigned char instr[])
{
long delta_tmp;
#define WRITE_DELTA(X) \
delta_tmp=X>>21; if (delta_tmp>0) out << Q_UINT8((delta_tmp&127)|128); \
delta_tmp=X>>14; if (delta_tmp>0) out << Q_UINT8((delta_tmp&127)|128); \
delta_tmp=X>>7; if (delta_tmp>0) out << Q_UINT8((delta_tmp&127)|128); \
out << Q_UINT8(X&127)
double ll=log10(pow(2.0,1.0/12.0));
if ( write_to.isSequentialAccess() || !write_to.isWritable())
qFatal("writeMidi() requires a writable random access IODevice");
QDataStream out( &write_to );
// Header
out.writeRawBytes("MThd",4);
out << Q_UINT32(6)
<< Q_UINT16(1) // mode
<< Q_UINT16(3) // # of tracks
<< Q_UINT16(96); // ticks / quarter
for (int n=0;n<3;n++)
{
out.writeRawBytes("MTrk",4);
qlonglong lp = write_to.at();
out << Q_UINT32(0); // chunklength
WRITE_DELTA(0); // set instrument
out << Q_UINT8(0xc0+n)
<< Q_UINT8(instr[n]);
unsigned short start=snd[n*2+0] | (snd[n*2+1]<<8);
unsigned short end=((snd[n*2+2] | (snd[n*2+3]<<8)))-5;
for (unsigned short pos=start; pos<end; pos+=5)
{
unsigned short freq, dur;
dur=(snd[pos+0] | (snd[pos+1]<<8))*4;
freq=((snd[pos+2] & 0x3F) << 4) + (snd[pos+3] & 0x0F);
if (snd[pos+2]>0)
{
double fr;
int note;
// I don't know, what frequency equals midi note 0 ...
// This moves the song 3 octaves down:
fr=(log10(111860.0 / (double)freq) / ll)-36;
note=(int)floor(fr);
if (note<0) note=0;
if (note>127) note=127;
// note on
WRITE_DELTA(0);
out << Q_UINT8(0x90+n)
<< Q_UINT8(note)
<< Q_UINT8(100);
// note off
WRITE_DELTA(dur);
out << Q_UINT8(0x80+n)
<< Q_UINT8(note)
<< Q_UINT8(0);
}
else
{
// note on
WRITE_DELTA(0);
out << Q_UINT8(0x90+n)
<< Q_UINT8(0)
<< Q_UINT8(0);
// note off
WRITE_DELTA(dur);
out << Q_UINT8(0x80+n)
<< Q_UINT8(0)
<< Q_UINT8(0);
}
}
WRITE_DELTA(0);
out << Q_UINT8(0xff)
<< Q_UINT8(0x2f)
<< Q_UINT8(0x0);
qlonglong ep=write_to.at();
write_to.at(lp);
out << Q_UINT32((ep-lp)-4);
write_to.at(ep);
}
#undef WRITE_DELTA
}
static unsigned char s_selected_instr[3] = {0,0,0};
// Show a "Save as" file dialog and call the Midi export function
void showSaveAsMidi( QWidget* parent, const byte* snd )
{
class MyFileDialog : public Q3FileDialog
{
public:
MyFileDialog( QWidget* parent, const char* name ) :
Q3FileDialog( parent, name )
{
QLabel* label = new QLabel( "Channel instruments", this );
label->setAlignment( AlignAuto | AlignTop | ExpandTabs );
Q3VBox* butts = new Q3VBox(this);
butts->setSpacing ( 2 );
for (int i=0; i<3; ++i )
{
instr[i] = new Q3ComboBox( butts );
instr[i]->insertStrList( g_gm_instrument_names );
instr[i]->setCurrentItem( s_selected_instr[i] );
}
addWidgets( label, butts, 0 );
}
Q3ComboBox* instr[3];
} fd( parent, NULL );
fd.setMode( Q3FileDialog::AnyFile );
fd.setFilter( "MIDI files (*.mid *.midi)" );
if ( fd.exec() == QDialog::Accepted )
{
QString fname = fd.selectedFile();
if ( fname.find( '.' ) < 0 )
fname += ".mid";
QFile f( fname );
f.open( QIODevice::WriteOnly );
for (int i=0; i<3; ++i )
s_selected_instr[i] = (unsigned char)fd.instr[i]->currentItem();
writeMidi(snd, f, s_selected_instr);
f.close();
}
}

27
src/midi.h Normal file
View File

@@ -0,0 +1,27 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef MIDI_H
#define MIDI_H
class QWidget;
void showSaveAsMidi( QWidget* parent, const byte* snd );
#endif

194
src/object.cpp Normal file
View File

@@ -0,0 +1,194 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
* Almost all of this code was adapted from the Windows AGI Studio
* developed by Peter Kelly.
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include "game.h"
#include "words.h"
#include "object.h"
#include "menu.h"
#include <stdio.h>
#include <sys/types.h>
#ifndef _WIN32
#include <unistd.h>
#endif
#include <sys/stat.h>
#include <stdlib.h>
//****************************************************
//list of inventory objects
ObjList::ObjList()
{
}
//****************************************************
bool ObjList::GetItems()
{
string ThisItemName;
int NamePos;
int CurrentItem,ItemNamesStart,ThisNameStart;
byte lsbyte,msbyte;
CurrentItem = 0;
lsbyte = ResourceData.Data[0];
msbyte = ResourceData.Data[1];
ItemNamesStart = msbyte * 256 + lsbyte + 3;
MaxScreenObjects = ResourceData.Data[2];
do{
lsbyte = ResourceData.Data[3+CurrentItem*3];
msbyte = ResourceData.Data[3+CurrentItem*3+1];
ThisNameStart = (msbyte<<8)|lsbyte + 3;
RoomNum[CurrentItem] = ResourceData.Data[3+CurrentItem*3+2];
NamePos = ThisNameStart;
if (NamePos > ResourceData.Size)return false; //object name past end of file
ThisItemName = "";
do{
if(ResourceData.Data[NamePos] > 0){
ThisItemName += ResourceData.Data[NamePos];
NamePos++;
}
}while(ResourceData.Data[NamePos] != 0 && NamePos < ResourceData.Size);
ItemNames.add(ThisItemName);
CurrentItem++;
}while((CurrentItem+1)*3 < ItemNamesStart && CurrentItem < MaxItems);
return true;
}
//****************************************************
void ObjList::XORData ()
{
for(int i=0;i<ResourceData.Size;i++){
ResourceData.Data[i] ^= EncryptionKey[i%11];
}
}
//****************************************************
int ObjList::read(char *filename,bool FileIsEncrypted)
{
FILE *fptr=fopen(filename,"rb");
if(fptr==NULL){
menu->errmes("Error opening file %s",filename);
return 1;
}
struct stat buf;
fstat(fileno(fptr),&buf);
int size=buf.st_size;
if(size > MaxResourceSize){
menu->errmes("Error: File %s is too big (>%d bytes)",filename,MaxResourceSize);
return 1;
}
ItemNames.lfree();
ResourceData.Size = size;
fread( ResourceData.Data, ResourceData.Size, 1, fptr);
fclose(fptr);
if (FileIsEncrypted) {
XORData();
}
if(!GetItems()){
XORData();
FileIsEncrypted = !FileIsEncrypted;
if(!GetItems()){
menu->errmes("Error! Invalid OBJECT file.");
return 1;
}
}
if (ItemNames.num == 0){
menu->errmes("Error! 0 objects in file.");
return 1;
}
return 0;
}
//********************************************
int ObjList::save(char *filename,bool FileIsEncrypted)
{
byte lsbyte,msbyte;
int ItemNamesStart,ObjectFilePos;
int CurrentItem,CurrentChar;
FILE *fptr;
ResourceData.Size = ItemNames.num*3 + 5;
//3 bytes for each index entry, 3 bytes for header, 2 for '?' object
for (CurrentItem = 1;CurrentItem<=ItemNames.num;CurrentItem++){
if(ItemNames.at(CurrentItem-1) != "?")
ResourceData.Size+=ItemNames.at(CurrentItem-1).length()+1;
}
//create data
ItemNamesStart = ItemNames.num*3 + 3;
msbyte = (ItemNamesStart-3) / 256;
lsbyte = (ItemNamesStart-3) % 256;
ResourceData.Data[0] = lsbyte;
ResourceData.Data[1] = msbyte;
ResourceData.Data[2] = MaxScreenObjects;
ResourceData.Data[3] = lsbyte;
ResourceData.Data[4] = msbyte;
ResourceData.Data[5] = 0;
ResourceData.Data[ItemNamesStart] = '?';
ResourceData.Data[ItemNamesStart + 1] = 0;
ObjectFilePos = ItemNamesStart + 2;
for (CurrentItem = 1;CurrentItem<=ItemNames.num;CurrentItem++){
if (ItemNames.at(CurrentItem-1) == "?"){
ResourceData.Data[CurrentItem*3] = ResourceData.Data[0];
ResourceData.Data[CurrentItem*3+1] = ResourceData.Data[1];
ResourceData.Data[CurrentItem*3+2] = RoomNum[CurrentItem-1];
}
else{
msbyte = (ObjectFilePos-3) / 256;
lsbyte = (ObjectFilePos-3) % 256;
ResourceData.Data[CurrentItem*3] = lsbyte;;
ResourceData.Data[CurrentItem*3+1] = msbyte;
ResourceData.Data[CurrentItem*3+2] = RoomNum[CurrentItem-1];
for (CurrentChar = 0; CurrentChar<(int)ItemNames.at(CurrentItem-1).length();CurrentChar++){
ResourceData.Data[ObjectFilePos] = ItemNames.at(CurrentItem-1)[CurrentChar];
ObjectFilePos++;
}
ResourceData.Data[ObjectFilePos] = 0;
ObjectFilePos++;
}
}//end create data
fptr = fopen(filename,"wb");
if(fptr==NULL){
menu->errmes("Error opening file %s !",filename);
return 1;
}
if(FileIsEncrypted)XORData();
fwrite(ResourceData.Data,ResourceData.Size,1,fptr);
fclose(fptr);
return 0;
}
//*****************************************
void ObjList::clear()
{
ItemNames.lfree();
ItemNames.add("?");
memset(RoomNum,0,sizeof(RoomNum));
}

44
src/object.h Normal file
View File

@@ -0,0 +1,44 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef OBJECT_H
#define OBJECT_H
#include "util.h"
#define MaxItems 256
//the list of inventory objects
class ObjList
{
public:
ObjList();
TStringList ItemNames;
byte RoomNum[MaxItems];
byte MaxScreenObjects; //what this is for ?
void XORData();
int read(char *filename,bool FileIsEncrypted);
int save(char *filename,bool FileIsEncrypted);
bool GetItems();
void clear();
};
#endif

363
src/objedit.cpp Normal file
View File

@@ -0,0 +1,363 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include "game.h"
#include "object.h"
#include "objedit.h"
#include "menu.h"
#include <stdio.h>
#include <sys/types.h>
#ifndef _WIN32
#include <unistd.h>
#endif
#include <sys/stat.h>
#include <stdlib.h>
#include <ctype.h>
#include <qapplication.h>
#include <q3filedialog.h>
//Added by qt3to4:
#include <Q3HBoxLayout>
#include <QCloseEvent>
#include <Q3BoxLayout>
#include <QShowEvent>
#include <QLabel>
#include <Q3PopupMenu>
#include <QHideEvent>
#include <Q3VBoxLayout>
//*****************************************
//Inventory object editor
ObjEdit::ObjEdit( QWidget *parent, const char *nam, int win_num)
: QWidget( parent, nam, Qt::WDestructiveClose )
{
setCaption("Object Editor");
setMinimumSize(400,400);
winnum = win_num;
objlist = new ObjList();
Q3PopupMenu *file = new Q3PopupMenu( this );
Q_CHECK_PTR( file );
file->insertItem( "New", this, SLOT(new_file()) );
file->insertItem( "Open", this, SLOT(open_file()) );
file->insertItem( "Save", this, SLOT(save_file()) );
file->insertItem( "Save As", this, SLOT(save_as_file()) );
file->insertSeparator();
file->insertItem( "Close", this, SLOT(close()) );
options = new Q3PopupMenu( this );
Q_CHECK_PTR( options );
encrypted = options->insertItem( "Encrypted", this, SLOT(encrypted_cb()) );
options->setItemChecked(encrypted,true);
QMenuBar *menu = new QMenuBar(this);
Q_CHECK_PTR( menu );
menu->insertItem( "File", file );
menu->insertItem( "Options", options );
menu->setSeparator( QMenuBar::InWindowsStyle );
Q3BoxLayout *all = new Q3VBoxLayout(this,14);
all->setMenuBar(menu);
list = new Q3ListBox(this);
list->setMinimumSize(400,400);
list->setColumnMode (1);
connect( list, SIGNAL(highlighted(int)), SLOT(select_object(int)) );
connect( list, SIGNAL(selected(int)), SLOT(select_object(int)) );
all->addWidget(list);
name = new QLineEdit(this);
connect( name, SIGNAL(returnPressed()), SLOT(name_cb()) );
all->addWidget(name);
Q3BoxLayout *down = new Q3HBoxLayout(all,4);
add = new QPushButton("&Add",this);
connect( add, SIGNAL(clicked()), SLOT(add_cb()) );
down->addWidget(add);
del = new QPushButton("&Delete",this);
connect( del, SIGNAL(clicked()), SLOT(del_cb()) );
down->addWidget(del);
QLabel *label = new QLabel("Room no:",this);
down->addWidget(label);
num = new QLineEdit(this);
connect( num, SIGNAL(returnPressed()), SLOT(num_cb()) );
down->addWidget(num);
left = new QPushButton("<",this);
connect( left, SIGNAL(clicked()), SLOT(left_cb()) );
down->addWidget(left);
right = new QPushButton(">",this);
connect( right, SIGNAL(clicked()), SLOT(right_cb()) );
down->addWidget(right);
adjustSize();
filename = "";
changed=false;
}
//*****************************************
void ObjEdit::open()
{
sprintf(tmp,"%s/object",game->dir.c_str());
open(tmp);
show();
}
//*****************************************
void ObjEdit::deinit()
{
delete objlist;
winlist[winnum].type=-1;
if(window_list && window_list->isVisible())window_list->draw();
}
//*********************************************
void ObjEdit::hideEvent( QHideEvent * )
{
if(window_list && window_list->isVisible())window_list->draw();
}
//*********************************************
void ObjEdit::showEvent( QShowEvent * )
{
if(window_list && window_list->isVisible())window_list->draw();
}
//*****************************************
void ObjEdit::closeEvent( QCloseEvent *e )
{
if(changed){
switch ( QMessageBox::warning( this, "ObjEdit",
"Save changes to OBJECT file ?",
"Yes",
"No",
"Cancel",
0, 2) ) {
case 0: // yes
save_file();
deinit();
e->accept();
break;
case 1: // no
deinit();
e->accept();
break;
default: // cancel
e->ignore();
break;
}
}
else{
deinit();
e->accept();
}
}
//*****************************************
void ObjEdit::open(char *name)
{
int ret = objlist->read(name,false);
if(ret)return;
filename = name;
list->clear();
for(int i=0;i<objlist->ItemNames.num;i++){
sprintf(tmp,"%d. %s",i,objlist->ItemNames.at(i).c_str());
list->insertItem(tmp);
}
list->show();
list->setCurrentItem(0);
changed=false;
}
//*****************************************
void ObjEdit::open_file()
{
Q3FileDialog *f = new Q3FileDialog(0,"Open",true);
const char *filters[] = {"object","All files (*)",NULL};
f->setFilters(filters);
f->setCaption("Open");
f->setMode(Q3FileDialog::ExistingFile);
f->setDir(game->dir.c_str());
if ( f->exec() == QDialog::Accepted ) {
if ( !f->selectedFile().isEmpty() )
open((char *)f->selectedFile().latin1());
}
}
//*****************************************
void ObjEdit::save_file()
{
if(filename==""){
save_as_file();
}
else{
objlist->save((char *)filename.c_str(),options->isItemChecked(encrypted));
changed=false;
}
}
//*****************************************
void ObjEdit::save_as_file()
{
Q3FileDialog *f = new Q3FileDialog(0,"Save",true);
const char *filters[] = {"object","All files (*)",NULL};
f->setFilters(filters);
f->setCaption("Save");
f->setMode(Q3FileDialog::AnyFile);
f->setDir(game->dir.c_str());
if ( f->exec() == QDialog::Accepted ) {
if ( !f->selectedFile().isEmpty() ){
objlist->save((char *)f->selectedFile().latin1(),options->isItemChecked(encrypted));
changed=false;
}
}
}
//*****************************************
void ObjEdit::new_file()
{
objlist->clear();
CurObject = 0;
list->clear();
list->insertItem("0. ?");
list->setCurrentItem(CurObject);
changed=false;
}
//*****************************************
void ObjEdit::select_object(int n)
{
name->setText(objlist->ItemNames.at(n).c_str());
sprintf(tmp,"%d",objlist->RoomNum[n]);
num->setText(tmp);
CurObject = n;
}
//*****************************************
void ObjEdit::add_cb()
{
objlist->ItemNames.add("?");
CurObject = objlist->ItemNames.num-1;
objlist->RoomNum[CurObject]=0;
sprintf(tmp,"%d. ?",CurObject);
list->insertItem(tmp);
list->setCurrentItem(CurObject);
changed=true;
}
//*****************************************
void ObjEdit::del_cb()
{
objlist->ItemNames.replace(CurObject,"?");
sprintf(tmp,"%d. ?",CurObject);
list->changeItem(tmp,CurObject);
changed=true;
}
//*****************************************
void ObjEdit::left_cb()
{
if(objlist->RoomNum[CurObject]>0){
objlist->RoomNum[CurObject]--;
sprintf(tmp,"%d",objlist->RoomNum[CurObject]);
num->setText(tmp);
changed=true;
}
}
//*****************************************
void ObjEdit::right_cb()
{
if(objlist->RoomNum[CurObject]<255){
objlist->RoomNum[CurObject]++;
sprintf(tmp,"%d",objlist->RoomNum[CurObject]);
num->setText(tmp);
changed=true;
}
}
//*****************************************
void ObjEdit::num_cb()
{
char *str = (char *)num->text().latin1();
int k = atoi(str);
if(!strcmp(str,"0") || (k>0&&k<256) ){
objlist->RoomNum[CurObject] = k;
changed=true;
}
else{
sprintf(tmp,"%d",objlist->RoomNum[CurObject]);
num->setText(tmp);
}
}
//*****************************************
void ObjEdit::name_cb()
{
char *str = (char *)name->text().latin1();
objlist->ItemNames.replace(CurObject,str);
sprintf(tmp,"%d. %s",CurObject,str);
list->changeItem(tmp,CurObject);
changed=true;
}
//*****************************************
void ObjEdit::encrypted_cb()
{
options->setItemChecked(encrypted,!options->isItemChecked(encrypted));
}
//*****************************************

81
src/objedit.h Normal file
View File

@@ -0,0 +1,81 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef OBJEDIT_H
#define OBJEDIT_H
#include <qwidget.h>
#include <qlabel.h>
#include <qpushbutton.h>
#include <qlayout.h>
#include <q3listbox.h>
#include <qmessagebox.h>
#include <qlineedit.h>
#include <qevent.h>
//Added by qt3to4:
#include <Q3PopupMenu>
#include <QShowEvent>
#include <QHideEvent>
#include <QCloseEvent>
#include "util.h"
#include "object.h"
//inventory objects editor
class ObjEdit : public QWidget
{
Q_OBJECT
public:
ObjEdit( QWidget *parent=0, const char *name=0, int winnum=0);
void open();
public slots:
void open_file();
void save_file();
void save_as_file();
void new_file();
void select_object(int);
void add_cb();
void del_cb();
void left_cb();
void right_cb();
void num_cb();
void name_cb();
void encrypted_cb();
protected:
int winnum;
Q3ListBox *list;
QLineEdit *name,*num;
QPushButton *add,*del,*left,*right;
Q3PopupMenu *options;
int encrypted;
int CurObject;
bool changed;
string filename;
ObjList *objlist;
void open(char *);
void save(char *);
void deinit();
void closeEvent( QCloseEvent *e );
void showEvent( QShowEvent * );
void hideEvent( QHideEvent * );
};
#endif

297
src/options.cpp Normal file
View File

@@ -0,0 +1,297 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include "options.h"
#include "game.h"
#include <stdlib.h>
#include <qapplication.h>
#include <q3filedialog.h>
//Added by qt3to4:
#include <Q3BoxLayout>
#include <Q3HBoxLayout>
#include <Q3VBoxLayout>
#include <QLabel>
Options *options;
//***********************************************
Options::Options( QWidget *parent, const char *name)
: Q3TabDialog( parent, name)
{
setCaption("Settings");
set_general();
set_directories();
set_logedit();
set_interpreter();
connect( this, SIGNAL( applyButtonPressed() ), SLOT( apply() ) );
setDefaultButton();
connect( this, SIGNAL( defaultButtonPressed() ), SLOT( defaults() ) );
setCancelButton();
set_settings();
}
//***********************************************
void Options::set_general()
{
QWidget *general = new QWidget(this);
Q3BoxLayout *all = new Q3VBoxLayout(general,10);
Q3GroupBox *b1 = new Q3GroupBox(2,Horizontal,"",general);
QLabel *l = new QLabel("Default resource type",b1);
l->setText("Default resource type"); //to avoid compilation warning
type = new QComboBox(false,b1,"type");
type->insertItem( "LOGIC" );
type->insertItem( "PICTURE" );
type->insertItem( "VIEW" );
type->insertItem( "SOUND" );
QLabel *l2 = new QLabel("Picedit style",b1);
l2->setText("Picedit style"); //to avoid compilation warning
picstyle = new QComboBox(false,b1,"picstyle");
picstyle->insertItem( "One window" );
picstyle->insertItem( "Two windows" );
all->addWidget(b1);
Q3ButtonGroup *extract = new Q3ButtonGroup(2,Horizontal,"Extract logic as",general);
extract->setMaximumSize(200,100);
extract->setExclusive(true);
text = new QRadioButton("Text",extract);
binary = new QRadioButton("Binary",extract);
all->addWidget(extract);
addTab(general,"General");
}
//***********************************************
void Options::set_logedit()
{
QWidget *logedit = new QWidget(this);
Q3BoxLayout *all = new Q3VBoxLayout(logedit,10);
messages = new QCheckBox("Show all messages at end (not just unused ones)",logedit);
all->addWidget(messages);
elses = new QCheckBox("Show all elses as gotos",logedit);
all->addWidget(elses);
special = new QCheckBox("Show special syntax (e.g. v30=4)",logedit);
all->addWidget(special);
addTab(logedit,"Logic editor");
}
//***********************************************
void Options::set_directories()
{
QWidget *dirs = new QWidget(this);
Q3BoxLayout *all = new Q3VBoxLayout(dirs,10);
Q3GroupBox *src = new Q3GroupBox(3,Horizontal,"Logic source directory",dirs);
reldir = new QRadioButton("[Game_dir/]",src);
connect(reldir,SIGNAL(clicked()),SLOT(set_reldir()));
relname = new QLineEdit(src);
QLabel *l = new QLabel(" ",src); //dummy label to keep table alignment
l->setText(" "); //to avoid compilation warning
absdir = new QRadioButton("Full path",src);
connect(absdir,SIGNAL(clicked()),SLOT(set_absdir()));
absname = new QLineEdit(src);
QPushButton *browse = new QPushButton("Browse",src);
connect(browse,SIGNAL(clicked()),SLOT(browse_abs()));
all->addWidget(src);
Q3BoxLayout *b1 = new Q3HBoxLayout(all);
QLabel *lt = new QLabel("Template:",dirs);
b1->addWidget(lt);
templatedir = new QLineEdit(dirs);
b1->addWidget(templatedir);
QPushButton *browse1 = new QPushButton("Browse",dirs);
b1->addWidget(browse1);
connect(browse1,SIGNAL(clicked()),SLOT(browse_template()));
Q3BoxLayout *b2 = new Q3HBoxLayout(all);
QLabel *lh = new QLabel("Help:",dirs);
b2->addWidget(lh);
helpdir = new QLineEdit(dirs);
b2->addWidget(helpdir);
QPushButton *browse2 = new QPushButton("Browse",dirs);
b2->addWidget(browse2);
connect(browse2,SIGNAL(clicked()),SLOT(browse_help()));
addTab(dirs,"Directories");
}
//***********************************************
void Options::set_interpreter()
{
QWidget *interp = new QWidget(this);
Q3BoxLayout *all = new Q3VBoxLayout(interp,10);
QLabel *l = new QLabel("Interpreter command line:\n(will be invoked with the\ncurrent directory == game_directory)",interp);
all->addWidget(l);
Q3BoxLayout *b1 = new Q3HBoxLayout(all);
command = new QLineEdit(interp);
b1->addWidget(command);
QPushButton *browse = new QPushButton("Browse",interp);
browse->setMaximumSize(80,60);
connect(browse,SIGNAL(clicked()),SLOT(browse_interpreter()));
b1->addWidget(browse);
addTab(interp,"Interpreter");
}
//***********************************************
void Options::apply()
{
game->res_default=type->currentItem();
game->save_logic_as_text=text->isChecked();
game->show_all_messages=messages->isChecked();
game->show_elses_as_gotos=elses->isChecked();
game->show_special_syntax=special->isChecked();
game->reldir=reldir->isChecked();
game->command=string((char *)command->text().latin1());
if(game->reldir){
game->srcdirname=string((char *)relname->text().latin1());
}
else{
game->srcdirname=string((char *)absname->text().latin1());
}
game->templatedir=string((char *)templatedir->text().latin1());
game->helpdir=string((char *)helpdir->text().latin1());
game->picstyle=picstyle->currentItem();
game->save_settings();
hide();
}
//***********************************************
void Options::defaults()
{
game->defaults();
set_settings();
}
//***********************************************
void Options::set_settings()
{
type->setCurrentItem(game->res_default);
text->setChecked(game->save_logic_as_text);
messages->setChecked(game->show_all_messages);
elses->setChecked(game->show_elses_as_gotos);
special->setChecked(game->show_special_syntax);
reldir->setChecked(game->reldir);
absdir->setChecked(!(game->reldir));
command->setText(game->command.c_str());
if(game->reldir){
relname->setText(game->srcdirname.c_str());
absname->clear();
}
else{
absname->setText(game->srcdirname.c_str());
relname->clear();
}
templatedir->setText(game->templatedir.c_str());
helpdir->setText(game->helpdir.c_str());
picstyle->setCurrentItem(game->picstyle);
}
//***********************************************
void Options::browse_abs()
{
QString s (Q3FileDialog::getExistingDirectory ());
if(s.isNull())return;
absname->setText(s);
}
//***********************************************
void Options::browse_template()
{
QString s (Q3FileDialog::getExistingDirectory ());
if(s.isNull())return;
templatedir->setText(s);
}
//***********************************************
void Options::browse_help()
{
QString s (Q3FileDialog::getExistingDirectory ());
if(s.isNull())return;
helpdir->setText(s);
}
//***********************************************
void Options::browse_interpreter()
{
QString s (Q3FileDialog::getOpenFileName ());
if(s.isNull())return;
command->setText(s);
}
//***********************************************
void Options::set_reldir()
{
absdir->setChecked(false);
}
//***********************************************
void Options::set_absdir()
{
reldir->setChecked(false);
}
//***********************************************

83
src/options.h Normal file
View File

@@ -0,0 +1,83 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef OPTIONS_H
#define OPTIONS_H
#include <qwidget.h>
#include <qlabel.h>
#include <qpushbutton.h>
#include <qlayout.h>
#include <q3listbox.h>
#include <qmessagebox.h>
#include <qlineedit.h>
#include <qradiobutton.h>
#include <q3buttongroup.h>
#include <qcheckbox.h>
#include <q3multilineedit.h>
#include <qpixmap.h>
#include <qlineedit.h>
#include <qcombobox.h>
#include <qevent.h>
#include <q3tabdialog.h>
#include "util.h"
#include "wutil.h"
#include "view.h"
class Options : public Q3TabDialog
{
Q_OBJECT
public:
Options( QWidget *parent=0, const char *name=0);
QComboBox *type,/* *style,*/ *picstyle;
QCheckBox *messages,*elses,*special;
QRadioButton *text,*binary;
QLineEdit *relname,*absname;
QRadioButton *reldir,*absdir;
QLineEdit *command,*templatedir,*helpdir;
public slots:
void set_general();
void set_logedit();
void set_directories();
void set_interpreter();
void set_settings();
void apply();
void defaults();
void browse_abs();
void browse_template();
void browse_help();
void browse_interpreter();
void set_reldir();
void set_absdir();
};
extern Options *options;
extern char tmp[];
#endif

1490
src/picedit.cpp Normal file

File diff suppressed because it is too large Load Diff

192
src/picedit.h Normal file
View File

@@ -0,0 +1,192 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef PICEDIT_H
#define PICEDIT_H
#include <qwidget.h>
#include <qlabel.h>
#include <qpushbutton.h>
#include <qlayout.h>
#include <qnamespace.h>
#include <qmessagebox.h>
#include <q3multilineedit.h>
#include <qevent.h>
#include <q3scrollview.h>
#include <qpixmap.h>
#include <qimage.h>
#include <qstatusbar.h>
#include <qcheckbox.h>
#include <qpaintdevice.h>
//Added by qt3to4:
#include <QCloseEvent>
#include <QShowEvent>
#include <QPaintEvent>
#include <QResizeEvent>
#include <QMouseEvent>
#include <QHideEvent>
#include <QKeyEvent>
#include "util.h"
#include "wutil.h"
#include "picture.h"
#include "resources.h"
class PicEdit;
class Palette1 : public QWidget
{
Q_OBJECT
public:
Palette1( QWidget *parent=0, const char *name=0, PicEdit *w=0);
int left,right;
protected:
PicEdit *picedit;
void paintEvent(class QPaintEvent *);
void mousePressEvent(QMouseEvent* event);
};
//************************************************
class PCanvas : public Q3ScrollView
{
Q_OBJECT
public:
PCanvas( QWidget *parent=0, const char *name=0, PicEdit *w=0);
int pixsize;
int cur_w,cur_h;
bool bg_loaded,bg_on;
bool linedraw;
bool pri_lines;
int x0,y0,x1,y1;
void line(bool mode);
void load_bg(char *filename);
void draw(int ResNum);
void update();
void setSize(int w,int h);
void setPixsize(int pixsize);
protected:
int CurColor;
Picture *picture;
QPixmap pixmap;
QImage bgpix;
PicEdit *picedit;
void closeEvent( QCloseEvent *e );
void showEvent( QShowEvent *);
void hideEvent( QHideEvent *);
void keyPressEvent( QKeyEvent * );
void viewportMousePressEvent(QMouseEvent* e);
void viewportMouseMoveEvent(QMouseEvent* e);
void drawContents ( QPainter * p, int clipx, int clipy, int clipw, int cliph ) ;
bool focusNextPrevChild ( bool next ) ;
};
//************************************************
class ViewData: public QWidget
{
Q_OBJECT
public:
ViewData( QWidget *parent=0, const char *name=0,Picture *p=0);
public slots:
void read();
protected:
QCheckBox *comments,*wrap;
Q3MultiLineEdit *codes;
TStringList data;
Picture *picture;
int maxcol;
void getmaxcol();
void resizeEvent( QResizeEvent * );
void KeyPressEvent( QKeyEvent * );
};
//************************************************
class PicEdit : public QWidget
{
Q_OBJECT
public:
PicEdit( QWidget *parent=0, const char *name=0,int winnum=0,ResourcesWin *res=0);
void open(int ResNum);
Picture *picture;
Q3ButtonGroup *tool;
QRadioButton *line,*step,*pen,*fill,*brush;
QRadioButton *pic,*pri;
QStatusBar *status;
QWidget *pricolor;
QCheckBox *bg,*prilines;
ResourcesWin *resources_win;
bool changed;
bool closing,hiding,showing;
int pri_mode;
public slots:
void open();
void open_file();
void save_file();
void save_to_game();
void save_to_game_as();
void delete_picture();
void view_data();
void background();
void zoom_minus();
void zoom_plus();
void change_drawmode(int);
void change_tool(int);
void change_size(int);
void change_shape(int);
void change_type(int);
void home_cb();
void end_cb();
void left_cb();
void right_cb();
void del_cb();
void wipe_cb();
void set_pos();
void show_pos();
void editor_help();
protected:
int PicNum;
int winnum;
PCanvas *canvas;
Palette1 *palette;
QLineEdit *pos,*codeline,*comments;
ViewData *viewdata;
void open(char *filename);
void save(char *filename);
void deinit();
void closeEvent( QCloseEvent *e );
void showEvent( QShowEvent *);
void hideEvent( QHideEvent *);
void update_palette();
void update_tools();
bool focusNextPrevChild ( bool next ) ;
};
#endif

1562
src/picture.cpp Normal file

File diff suppressed because it is too large Load Diff

218
src/picture.h Normal file
View File

@@ -0,0 +1,218 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef PICTURE_H
#define PICTURE_H
#ifndef __GNUCPP__
#include <stdint.h>
#endif
#include <qimage.h>
#include <QColor>
#include "linklist.h"
#include "util.h"
#define MAX_W 320
#define MAX_H 200
#define MAX_HH 168
//the actual height of the picture is 168 (to leave space for menu and text input)
typedef unsigned short int word;
typedef uint8_t byte;
#define M_LEFT 0
#define M_RIGHT 2
#define CIRCLE 0
#define SQUARE 1
#define SPRAY 0
#define SOLID 1
#define T_LINE 0
#define T_PEN 1
#define T_STEP 2
#define T_FILL 3
#define T_BRUSH 4
#define QUMAX 4000
#define EMPTY 0xFF
typedef struct {
short x,y;
byte c;
QColor cc;
}Point;
typedef struct {
int n;
Point p[370];
}Points;
//bitmap picture - for preview
class BPicture {
public:
BPicture();
byte **picture;
byte **priority;
void show(byte *, int);
protected:
byte buf[QUMAX+1];
word rpos, spos;
bool picDrawEnabled,priDrawEnabled;
byte picColour, priColour, patCode, patNum;
void qstore(byte q);
byte qretrieve();
void picPSet(word x, word y);
void priPSet(word x, word y);
void pset(word x, word y);
byte picGetPixel(word x, word y);
byte priGetPixel(word x, word y);
int round(float aNumber, float dirn);
void drawline(word x1, word y1, word x2, word y2);
bool okToFill(byte x, byte y);
void agiFill(word x, word y);
void xCorner(byte **data);
void yCorner(byte **data);
void relativeDraw(byte **data);
void fill(byte **data);
void absoluteLine(byte **data);
void plotPattern(byte x, byte y);
void plotBrush(byte **data);
};
//'list' format picture - for edit
class Picture {
public:
Picture();
byte picture[MAX_W*MAX_H];
byte priority[MAX_W*MAX_H];
byte *pptr;
bool bg_on;
QImage *bgpix;
Points points,points0,points1;
Points *curp,*newp;
void load(byte *, int);
int open(char *filename);
int open(int ResNum);
void save();
int save(char *filename);
int save(int ResNum);
void newpic();
void draw();
void init();
void set_mode(int);
void clear_tools();
void init_tool();
void home_proc();
void end_proc();
void left_proc();
void right_proc();
void del_proc();
void wipe_proc();
void tool_proc(int);
void choose_color(int button, int color);
void set_brush(int mode,int val);
int button_action(int newX, int newY);
int move_action(int newX, int newY);
char *showPos(int *code,int *val);
int setBufPos(int);
void viewData(TStringList *data);
void status(int mode);
void refill( struct picCodeNode *temp_fill_start, struct picCodeNode *temp_fill_end,int mode);
int drawing_mode;
int tool;
int brushSize,brushShape,brushTexture;
byte picColour, priColour, patCode, patNum, curcol;
bool picDrawEnabled,priDrawEnabled;
int bufPos; /* This variable holds current offset into buffer */
int bufLen;
bool refill_pic,refill_pri;
int refill_x,refill_y;
protected:
struct picCodeNode picCodes;
struct picCodeNode *picPos;
struct picCodeNode *picStart;
struct picCodeNode *picLast;
byte buf[QUMAX+1];
word rpos, spos;
int addMode;
bool add_pic,add_pri;
int code_pic,col_pic,code_pri,col_pri;
void dldelete();
void removeAction();
void wipeAction();
void dlstore(struct picCodeNode *i);
void displayList();
void freeList();
void moveBack();
void moveForward();
void moveToStart();
void moveToEnd();
void moveBackAction();
void moveForwardAction();
byte getCode(struct picCodeNode **temp);
byte testCode(struct picCodeNode **temp);
void qstore(byte q);
byte qretrieve();
void picPSet(word x, word y);
void priPSet(word x, word y);
void pset(word x, word y);
byte picGetPixel(word x, word y);
byte priGetPixel(word x, word y);
int round(float aNumber, float dirn);
void drawline(word x1, word y1, word x2, word y2);
bool okToFill(byte x, byte y);
void agiFill(word x, word y);
void xCorner(struct picCodeNode **temp);
void yCorner(struct picCodeNode **temp);
void relativeDraw(struct picCodeNode **temp);
void fill(struct picCodeNode **temp);
void absoluteLine(struct picCodeNode **temp);
void plotPattern(byte x, byte y);
void plotBrush(struct picCodeNode **temp);
void addCode(byte code);
void replaceCode(byte code);
void addPatCode();
void adjustDisp(int *dX, int *dY);
int clickX, clickY, dX, dY;
int stepClicks, numClicks;
bool firstClick;
void normline2(int x1, int y1, int x2, int y2);
void putpix2(int x,int y);
};
extern char tmp[];
#endif

650
src/preview.cpp Normal file
View File

@@ -0,0 +1,650 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include "resources.h"
#include "game.h"
#include "preview.h"
#include "picture.h"
#include "wutil.h"
#include "menu.h"
#include "logedit.h"
#include <stdio.h>
#include <q3buttongroup.h>
#include <qpixmap.h>
#include <qimage.h>
#include <QImageWriter>
#include <q3filedialog.h>
#include <qpainter.h>
//Added by qt3to4:
#include <Q3HBoxLayout>
#include <Q3StrList>
#include <QLabel>
#include <Q3GridLayout>
#include <QHideEvent>
#include <Q3VBoxLayout>
#include <Q3BoxLayout>
#include <QShowEvent>
#include <QPaintEvent>
#include <QCloseEvent>
#include "right_x.xpm"
#include "left_x.xpm"
//*****************************************
Preview::Preview( QWidget* parent, const char* name ,ResourcesWin *res ):
Q3WidgetStack(parent,name)
{
setCaption("Preview");
make_egacolors();
resources_win = res;
// Logic
w_logic = new QWidget (this);
w_logic->setMinimumSize(340,280);
Q3BoxLayout *d = new Q3VBoxLayout(w_logic,5);
p_logic = new LogEdit( w_logic,0,0,res,true );
d->addWidget(p_logic);
QPushButton *edit = new QPushButton("Edit",w_logic);
edit->setMaximumSize(80,60);
connect(edit,SIGNAL(clicked()),SLOT(double_click()));
d->addWidget(edit);
// Sound
w_sound = new QWidget (this);
w_sound->setMinimumSize(340,280);
Q3BoxLayout *d1 = new Q3VBoxLayout(w_sound, 5);
QLabel *l1 = new QLabel("Preview is not available !\nDouble-click to listen.\nOr click the 'Listen' button.",w_sound,0);
d1->addWidget(l1);
QPushButton *listen = new QPushButton("Listen",w_sound);
listen->setMaximumSize(120,60);
connect(listen,SIGNAL(clicked()),SLOT(double_click()));
d1->addWidget(listen);
QPushButton *save_as_midi = new QPushButton("Save as MIDI",w_sound);
save_as_midi->setMaximumSize(120,60);
connect(save_as_midi,SIGNAL(clicked()),SLOT(export_resource()));
d1->addWidget(save_as_midi);
d1->addStretch();
// Picture
w_picture = new QWidget (this,0);
w_picture->setMinimumSize(340,280);
Q3BoxLayout *pbox = new Q3VBoxLayout(w_picture,10);
p_picture = new PreviewPicture(w_picture,0,this);
p_picture->setFixedSize(MAX_W,MAX_HH);
pbox->addWidget(p_picture);
Q3BoxLayout *pbox1 = new Q3HBoxLayout(pbox,10);
visual = new QRadioButton("Visual",w_picture);
visual->setChecked(true);
pbox1->addWidget(visual);
priority = new QRadioButton("Priority",w_picture);
priority->setChecked(false);
pbox1->addWidget(priority);
p_picture->drawing_mode=0;
Q3ButtonGroup *bg = new Q3ButtonGroup(w_picture);
bg->hide();
bg->insert(visual,0);
bg->insert(priority,1);
connect( bg, SIGNAL(clicked(int)), SLOT(change_mode(int)) );
Q3BoxLayout *pbox2 = new Q3HBoxLayout(pbox,10);
QPushButton *pedit = new QPushButton("Edit",w_picture);
pedit->setMaximumWidth(100);
connect(pedit,SIGNAL(clicked()),SLOT(double_click()));
pbox2->addWidget(pedit,Qt::AlignCenter);
save_pic_butt = new QPushButton("Save as...",w_picture);
save_pic_butt->setMaximumWidth(100);
connect(save_pic_butt,SIGNAL(clicked()),SLOT(save_pic()));
pbox2->addWidget(save_pic_butt,Qt::AlignCenter);
formats_pic = new QComboBox(w_picture);
for (int i = 0; i < QImageWriter::supportedImageFormats().size(); ++i) {
formats_pic->insertItem(QImageWriter::supportedImageFormats().at(i).constData());
}
pbox2->addWidget(formats_pic);
pbox->addStretch();
// View
w_view = new QWidget (this,0);
w_view->setMinimumSize(340,240);
Q3BoxLayout *vbox = new Q3VBoxLayout(w_view,10);
int maxrow1=3,maxcol1=5;
Q3GridLayout *grid1 = new Q3GridLayout( vbox, maxrow1,maxcol1, 1 );
int i;
for(i=0;i<maxcol1;i++){
grid1->setColStretch(i,1);
grid1->addColSpacing(i,1);
}
for(i=0;i<maxrow1;i++){
grid1->setRowStretch(i,1);
grid1->addRowSpacing(i,2);
}
int row=0;int col=0;
QPixmap pright=QPixmap(right_x);
QPixmap pleft=QPixmap(left_x);
QLabel *looplabel = new QLabel("Loop:",w_view);
grid1->addWidget(looplabel,row,col,Qt::AlignRight); col++;
loopnum = new QLabel("0/0",w_view);
grid1->addWidget(loopnum,row,col,Qt::AlignLeft); col++;
QPushButton *loopleft = new QPushButton(w_view);
loopleft->setPixmap(pleft);
connect( loopleft, SIGNAL(clicked()), SLOT(previous_loop()) );
grid1->addWidget(loopleft,row,col,Qt::AlignRight); col++;
QPushButton *loopright = new QPushButton(w_view);
loopright->setPixmap(pright);
connect( loopright, SIGNAL(clicked()), SLOT(next_loop()) );
grid1->addWidget(loopright,row,col,Qt::AlignLeft); col++;
QPushButton *vedit = new QPushButton("Edit",w_view);
vedit->setMaximumWidth(100);
connect(vedit,SIGNAL(clicked()),SLOT(double_click()));
grid1->addWidget(vedit,row,col,Qt::AlignCenter); col++;
row++;col=0;
QLabel *cellabel = new QLabel("Cel:",w_view);
grid1->addWidget(cellabel,row,col,Qt::AlignRight); col++;
celnum = new QLabel("0/0",w_view);
grid1->addWidget(celnum,row,col,Qt::AlignLeft); col++;
QPushButton *celleft = new QPushButton(w_view);
celleft->setPixmap(pleft);
connect( celleft, SIGNAL(clicked()), SLOT(previous_cel()) );
grid1->addWidget(celleft,row,col,Qt::AlignRight); col++;
QPushButton *celright = new QPushButton(w_view);
celright->setPixmap(pright);
connect( celright, SIGNAL(clicked()), SLOT(next_cel()) );
grid1->addWidget(celright,row,col,Qt::AlignLeft); col++;
QPushButton *anim = new QPushButton("Animate",w_view);
connect(anim,SIGNAL(clicked()),SLOT(animate_cb()));
grid1->addWidget(anim,row,col,Qt::AlignCenter); col++;
row++;col=0;
save_view_butt = new QPushButton("Save as...",w_view);
save_view_butt->setMaximumWidth(100);
connect(save_view_butt,SIGNAL(clicked()),SLOT(save_view()));
grid1->addWidget(save_view_butt,row,col,Qt::AlignCenter); col++;
formats_view = new QComboBox(w_view);
// QStrList out = QImageIO::outputFormats ();
for (int i = 0; i < QImageWriter::supportedImageFormats().size(); ++i) {
formats_view->insertItem(QImageWriter::supportedImageFormats().at(i).constData());
}
grid1->addWidget(formats_view,row,col,Qt::AlignCenter); // Reference to the same widget used in picture
p_view = new PreviewView(w_view,0,this);
p_view->setMinimumSize(64,64);
p_view->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum ));
vbox->addWidget(p_view);
description = new Q3MultiLineEdit(w_view);
description->setReadOnly(true);
description->setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding ));
vbox->addWidget(description);
vbox->addStretch();
// Build the widget stack
addWidget( w_picture );
addWidget( w_view );
addWidget( w_sound );
addWidget( w_logic );
setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding ));
adjustSize();
animate=NULL;
}
//*****************************************
void Preview::open(int ResNum,int type)
{
switch(type){
case LOGIC:
if(animate){ animate->closeall(); animate=NULL; }
raiseWidget( w_logic );
p_logic->open(ResNum);
break;
case VIEW:
raiseWidget( w_view );
p_view->draw(ResNum);
break;
case PICTURE:
if(animate){ animate->closeall(); animate=NULL; }
raiseWidget( w_picture );
p_picture->draw(ResNum);
break;
case SOUND:
if(animate){ animate->closeall(); animate=NULL; }
raiseWidget( w_sound );
break;
}
show();
}
//*****************************************
void Preview::change_mode(int mode)
{
p_picture->drawing_mode=mode;
p_picture->update();
}
//******************************************************
void Preview::double_click()
{
resources_win->select_resource(resources_win->list->currentItem());
}
//******************************************************
void Preview::previous_loop()
{
if(p_view->view->CurLoop>0){
p_view->view->CurLoop--;
p_view->view->CurCel=0;
showlooppar();
showcelpar();
p_view->update();
}
}
//******************************************************
void Preview::next_loop()
{
if(p_view->view->CurLoop<p_view->view->NumLoops-1){
p_view->view->CurLoop++;
p_view->view->CurCel=0;
showlooppar();
showcelpar();
p_view->update();
}
}
//******************************************************
void Preview::previous_cel()
{
if(p_view->view->CurCel>0){
p_view->view->CurCel--;
showcelpar();
p_view->update();
}
}
//******************************************************
void Preview::prev_cel_cycle()
{
if(p_view->view->loops[p_view->view->CurLoop].NumCels<=1)return;
if(p_view->view->CurCel>0){
p_view->view->CurCel--;
}
else{
p_view->view->CurCel=p_view->view->loops[p_view->view->CurLoop].NumCels-1;
}
showcelpar();
p_view->update();
}
//******************************************************
void Preview::next_cel()
{
if(p_view->view->CurCel<p_view->view->loops[p_view->view->CurLoop].NumCels-1){
p_view->view->CurCel++;
showcelpar();
p_view->update();
}
}
//******************************************************
void Preview::next_cel_cycle()
{
if(p_view->view->loops[p_view->view->CurLoop].NumCels<=1)return;
if(p_view->view->CurCel<p_view->view->loops[p_view->view->CurLoop].NumCels-1){
p_view->view->CurCel++;
}
else{
p_view->view->CurCel=0;
}
showcelpar();
p_view->update();
}
//******************************************************
void Preview::showlooppar()
{
sprintf(tmp,"%d/%d",p_view->view->CurLoop,p_view->view->NumLoops-1);
loopnum->setText(tmp);
}
//******************************************************
void Preview::animate_cb()
{
if(animate==NULL)animate=new Animate(0,0,this,0);
animate->show();
}
//******************************************************
void Preview::showcelpar()
{
sprintf(tmp,"%d/%d",p_view->view->CurCel,p_view->view->loops[p_view->view->CurLoop].NumCels-1);
celnum->setText(tmp);
}
//******************************************************
void Preview::save_pic()
{
save_image( p_picture->pixmap, formats_pic->currentText().latin1() );
}
//******************************************************
void Preview::save_view()
{
save_image( p_view->pixmap, formats_view->currentText().latin1() );
}
//******************************************************
void Preview::save_image( QPixmap& pixmap, const char* format )
{
Q3FileDialog *f = new Q3FileDialog(0,"Save",true);
sprintf(tmp,"*.%s",format);
toLower(tmp);
const char *filters[] = {tmp,"All files (*)",NULL};
f->setFilters(filters);
f->setCaption("Save as image");
f->setMode(Q3FileDialog::AnyFile);
f->setDir(game->srcdir.c_str());
if ( f->exec() == QDialog::Accepted ) {
if ( !f->selectedFile().isEmpty() ){
if(!pixmap.save((char *)f->selectedFile().latin1(),format))
menu->errmes("Couldn't save picture !");
}
}
}
//******************************************************
void Preview::export_resource()
{
resources_win->export_resource();
}
//*****************************************
void Preview::deinit()
{
if(animate){
animate->closeall();
animate=NULL;
}
resources_win->preview=NULL;
if(window_list && window_list->isVisible())window_list->draw();
}
//*********************************************
void Preview::closeEvent( QCloseEvent *e )
{
deinit();
e->accept();
}
//*********************************************
void Preview::hideEvent( QHideEvent * )
{
if(window_list && window_list->isVisible())window_list->draw();
}
//*********************************************
void Preview::showEvent( QShowEvent * )
{
if(window_list && window_list->isVisible())window_list->draw();
}
//******************************************************
PreviewPicture::PreviewPicture( QWidget* parent, const char* name, Preview *p ):
QWidget(parent,name)
{
preview = p;
pixmap = QPixmap(MAX_W,MAX_HH);
ppicture = new BPicture();
}
//*****************************************
void PreviewPicture::draw(int ResNum)
{
int err = game->ReadResource(PICTURE,ResNum);
if(!err){
ppicture->show(ResourceData.Data,ResourceData.Size);
update();
}
}
//*****************************************
void PreviewPicture::update()
{
QPainter p(&pixmap);
byte **data;
int x,y;
byte c0=255,c;
data = (drawing_mode)?ppicture->priority:ppicture->picture;
for(y=0;y<MAX_HH;y++){
for(x=0;x<MAX_W;x++){
c=data[y][x];
if(c!=c0){
p.setPen(egacolor[c]);
c0=c;
}
p.drawPoint(x,y);
}
}
repaint();
}
//*****************************************
void PreviewPicture::paintEvent(QPaintEvent *)
{
QPainter p(this);
p.drawPixmap( 0, 0, pixmap );
}
//******************************************************
PreviewView::PreviewView( QWidget* parent, const char* name, Preview *p ):
QWidget(parent,name)
{
preview = p;
view = new View();
pixmap = QPixmap();
cur_w = cur_h = 0;
pixsize = 2;
}
//*****************************************
void PreviewView::paintEvent(QPaintEvent *)
{
QPainter p(this);
int W = preview->width();
int x = (W-pixsize*cur_w*2)/2;
p.drawPixmap( x, 0, pixmap );
}
//*****************************************
void PreviewView::update()
{
int x,y;
if(!view->opened)return;
int w = view->loops[view->CurLoop].cels[view->CurCel].width;
int h = view->loops[view->CurLoop].cels[view->CurCel].height;
bool mirror = (view->loops[view->CurLoop].mirror!=-1);
byte *data = view->loops[view->CurLoop].cels[view->CurCel].data;
if(cur_w != w || cur_h != h){
pixmap.resize(w*pixsize*2,h*pixsize);
cur_w=w;
cur_h=h;
}
QPainter p(&pixmap);
if(mirror){
for(y=0;y<h;y++){
for(x=0;x<w*2;x+=2){
p.fillRect(x*pixsize,y*pixsize,pixsize*2,pixsize,egacolor[data[y*w*2+w*2-2-x]]);
}
}
}
else{
for(y=0;y<h;y++){
for(x=0;x<w*2;x+=2){
p.fillRect(x*pixsize,y*pixsize,pixsize*2,pixsize,egacolor[data[y*w*2+x]]);
}
}
}
repaint();
}
//*****************************************
void PreviewView::draw(int ResNum)
{
int err = view->open(ResNum);
if(!err){
preview->showlooppar();
preview->showcelpar();
}
update();
if(!err && view->Description != ""){
show_description();
preview->description->show();
}
else{
preview->description->hide();
}
}
//*****************************************
void PreviewView::show_description()
{
int x,y,w,h,W,H,n;
unsigned int maxcol;
preview->description->hide();
w = (view->loops[view->CurLoop].cels[view->CurCel].width)*2*pixsize;
h = (view->loops[view->CurLoop].cels[view->CurCel].height)*pixsize;
resize(w,h);
W=preview->width();
H=preview->height();
x=this->x();
y=this->y();
preview->description->setGeometry(10,y+h+10,W-20,H-(y+h+20));
QFontMetrics f = fontMetrics();
maxcol = (W-20)/f.width('a');
preview->description->clear();
string ThisLine = "";
string ThisMessage = view->Description;
do{
if(ThisMessage.length() + ThisLine.length() > maxcol){
n = maxcol - ThisLine.length();
do{ n--; }while(!(n == 0 || ThisMessage[n]==' '));
if (n <= 0)n = maxcol-ThisLine.length();
ThisLine += ThisMessage.substr(0,n);
ThisMessage = (n < (int)ThisMessage.length())?ThisMessage.substr(n+1):"";
preview->description->insertLine(ThisLine.c_str(),-1);
ThisLine = "";
}
else{
ThisLine += ThisMessage;
ThisMessage = "";
}
}while(ThisMessage != "");
if(ThisLine != ""){
preview->description->insertLine(ThisLine.c_str(),-1);
}
}
//*****************************************

131
src/preview.h Normal file
View File

@@ -0,0 +1,131 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef PREVIEW_H
#define PREVIEW_H
#include "picture.h"
#include "view.h"
#include "resources.h"
#include <string>
#include <qwidget.h>
#include <q3widgetstack.h>
#include <qlabel.h>
#include <qlayout.h>
#include <qradiobutton.h>
#include <qpushbutton.h>
#include <qpixmap.h>
#include <q3multilineedit.h>
#include <qcombobox.h>
//Added by qt3to4:
#include <QShowEvent>
#include <QHideEvent>
#include <QCloseEvent>
#include <QPaintEvent>
class Animate;
class Preview;
//****************************************************
class PreviewView : public QWidget
{
Q_OBJECT
public:
PreviewView( QWidget *parent=0, const char *name=0, Preview *p=0);
Preview *preview;
View *view;
QPixmap pixmap;
int cur_w,cur_h;
int pixsize;
void draw(int ResNum);
void update();
void show_description();
protected:
void paintEvent(QPaintEvent *);
};
//****************************************************
class PreviewPicture : public QWidget
{
Q_OBJECT
public:
PreviewPicture( QWidget *parent=0, const char *name=0, Preview *p=0);
Preview *preview;
BPicture *ppicture;
QPixmap pixmap;
int drawing_mode;
void draw(int ResNum);
void update();
protected:
void paintEvent(QPaintEvent *);
};
class ResourcesWin;
class LogEdit;
//****************************************************
class Preview : public Q3WidgetStack
{
Q_OBJECT
public:
Preview( QWidget* parent = 0, const char* name=0, ResourcesWin *res=0);
Q3MultiLineEdit *description;
ResourcesWin *resources_win;
void open(int i,int type);
public slots:
void double_click();
void change_mode(int);
void previous_loop(void);
void next_loop(void);
void previous_cel(void);
void next_cel(void);
void prev_cel_cycle(void);
void next_cel_cycle(void);
void showlooppar();
void showcelpar();
void save_image( QPixmap& img, const char* format );
void save_pic();
void save_view();
void export_resource();
void animate_cb();
protected:
QComboBox *formats_pic, *formats_view;
QWidget *w_logic,*w_sound;
QWidget *w_picture;
LogEdit *p_logic;
PreviewPicture *p_picture;
QRadioButton *visual,*priority;
QPushButton *save_pic_butt, *save_view_butt;
QWidget *w_view;
PreviewView *p_view;
QPushButton *loopleft,*loopright,*celleft,*celright;
QLabel *loopnum,*celnum;
Animate *animate;
void deinit();
void closeEvent( QCloseEvent * );
void showEvent( QShowEvent * );
void hideEvent( QHideEvent * );
};
#endif

16
src/resource.h Normal file
View File

@@ -0,0 +1,16 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by agistudio.rc
//
#define IDI_ICON1 101
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

779
src/resources.cpp Normal file
View File

@@ -0,0 +1,779 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include "resources.h"
#include "game.h"
#include "logedit.h"
#include "viewedit.h"
#include "preview.h"
#include "menu.h"
#include "midi.h"
#include "bmp2agipic.h"
#include <q3widgetstack.h>
//Added by qt3to4:
#include <Q3HBoxLayout>
#include <QLabel>
#include <QHideEvent>
#include <Q3PopupMenu>
#include <Q3VBoxLayout>
#include <Q3BoxLayout>
#include <QShowEvent>
#include <QCloseEvent>
#include <stdio.h>
#ifdef _WIN32
#define strncasecmp(a, b, l) _stricmp(a, b)
#else
#include <unistd.h>
#endif
#include <sys/stat.h>
#include <stdlib.h>
//**********************************************************
ResourcesWin::ResourcesWin( QWidget* parent, const char* name, int win_num ):
QWidget(parent,name,Qt::WDestructiveClose)
{
setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ));
setCaption("resources");
winnum = win_num;
Q3PopupMenu *window = new Q3PopupMenu( this );
Q_CHECK_PTR( window );
window->insertItem ( "New", this, SLOT(new_resource_window()) );
window->insertSeparator();
window->insertItem ( "Close", this, SLOT(close()) );
resourceMenu = new Q3PopupMenu( this );
Q_CHECK_PTR( resourceMenu );
resourceMenu->insertItem ( "&Add", this, SLOT(add_resource()) );
resourceMenu->insertItem ( "&Extract", this, SLOT(extract_resource()) );
resourceMenu->insertItem ( "&Delete", this, SLOT(delete_resource()) );
resourceMenu->insertItem ( "&Renumber", this, SLOT(renumber_resource()) );
importMenuItemID = resourceMenu->insertItem ( "Import &bitmap", this, SLOT(import_resource()) );
resourceMenu->setItemEnabled(importMenuItemID, false);
resourceMenu->insertItem ( "Extract all", this, SLOT(extract_all_resource()) );
QMenuBar* resourceMenubar = new QMenuBar(this);
Q_CHECK_PTR( resourceMenubar );
resourceMenubar->insertItem ("Window", window );
resourceMenubar->insertItem( "&Resource", resourceMenu );
resourceMenubar->setSeparator( QMenuBar::InWindowsStyle );
Q3BoxLayout *hbox = new Q3HBoxLayout( this, 10 );
hbox->setMenuBar(resourceMenubar);
Q3BoxLayout *resbox = new Q3VBoxLayout( hbox, 10 );
type = new QComboBox(FALSE, this, "type");
type->insertItem( "LOGIC" );
type->insertItem( "PICTURE" );
type->insertItem( "VIEW" );
type->insertItem( "SOUND" );
connect( type, SIGNAL(activated(int)), SLOT(select_resource_type(int)) );
type->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ));
resbox->addWidget(type);
list = new Q3ListBox(this,"list");
list->setColumnMode (1);
list->setMinimumSize(200,300);
connect( list, SIGNAL(highlighted(int)), SLOT(highlight_resource(int)) );
connect( list, SIGNAL(selected(int)), SLOT(select_resource(int)) );
list->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::MinimumExpanding ));
selected = game->res_default;
resbox->addWidget(list);
msg = new QLabel( this, "message" );
msg->setAlignment( Qt::AlignLeft );
resbox->addWidget(msg);
addmenu = NULL;
preview = NULL;
closing = false;
Q3BoxLayout *prevbox = new Q3VBoxLayout(hbox,10);
Q3GroupBox* group = new Q3GroupBox( 1, Qt::Vertical, "Preview", this );
group->setMinimumSize(340+10*2,280+10*2);
group->setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding ));
previewPane = group;
prevbox->addWidget(previewPane);
adjustSize();
}
//********************************************************
void ResourcesWin::select_resource_type( int ResType )
{
QString str;
int i,k;
type->setCurrentItem(ResType);
selected = ResType;
// enable import item if resource type supports it
resourceMenu->setItemEnabled(importMenuItemID, selected == PICTURE );
// Show a resource list
list->hide();
list->clear();
for(i=0,k=0;i<256;i++){
if(game->ResourceInfo[ResType][i].Exists){
str.sprintf( "%s.%3d", ResTypeName[ResType],i);
list->insertItem( str );
ResourceIndex[k++]=i;
}
}
ResourceNum = k;
list->show();
first=true;
}
//********************************************************
void ResourcesWin::highlight_resource( int k )
{
int i = ResourceIndex[k];
int size = game->GetResourceSize(selected,i);
QString str;
str.sprintf("%d bytes",size);
msg->setText(str);
if(preview==NULL)
preview = new Preview(previewPane,0,this);
preview->open(i,selected);
preview->show();
}
//********************************************************
void ResourcesWin::select_resource( int k )
{
int i = ResourceIndex[k];
int size = game->GetResourceSize(selected,i);
int n;
extern void play_sound(int ResNum);
QString str;
str.sprintf("%d bytes",size);
msg->setText(str);
if((n=get_win())==-1)return;
switch(selected){
case LOGIC:
winlist[n].w.l=new LogEdit(NULL,NULL,n);
winlist[n].type=LOGIC;
winlist[n].w.l->open(i);
break;
case PICTURE:
winlist[n].w.p=new PicEdit(NULL,NULL,n);
winlist[n].type=PICTURE;
winlist[n].w.p->open(i);
break;
case VIEW:
winlist[n].w.v = new ViewEdit(NULL,NULL,n);
winlist[n].type=VIEW;
winlist[n].w.v->open(i);
break;
case SOUND:
play_sound(i);
break;
}
}
//********************************************************
void ResourcesWin::set_current( int n )
{
for(int i=0;i<ResourceNum;i++){
if(ResourceIndex[i]==n){
list->setCurrentItem(i);
break;
}
}
}
//*********************************************
void ResourcesWin::deinit( )
{
closing = true;
if(preview){
preview->close();
preview=NULL;
}
for(int i=0;i<MAXWIN;i++){
if(winlist[i].type==-1)continue;
switch(winlist[i].type){
case LOGIC:
if(winlist[i].w.l->resources_win==this)winlist[i].w.l->resources_win=NULL;
break;
case VIEW:
if(winlist[i].w.v->resources_win==this)winlist[i].w.v->resources_win=NULL;
break;
case PICTURE:
if(winlist[i].w.p->resources_win==this)winlist[i].w.p->resources_win=NULL;
break;
}
}
winlist[winnum].type=-1;
menu->dec_res();
if(window_list && window_list->isVisible())window_list->draw();
}
//*********************************************
void ResourcesWin::closeEvent( QCloseEvent *e )
{
deinit();
e->accept();
}
//*********************************************
void ResourcesWin::hideEvent( QHideEvent * )
{
if(preview && preview->isVisible())preview->showMinimized();
if(window_list && window_list->isVisible())window_list->draw();
}
//*********************************************
void ResourcesWin::showEvent( QShowEvent * )
{
if(preview && !preview->isVisible())preview->showNormal();
if(window_list && window_list->isVisible())window_list->draw();
}
//**********************************************
void ResourcesWin::new_resource_window()
{
menu->new_resource_window();
}
//**********************************************
void ResourcesWin::delete_resource()
{
int restype = selected;
int k = list->currentItem();
int resnum = ResourceIndex[k];
sprintf(tmp,"Really delete %s.%d ?",ResTypeName[restype],resnum);
switch( QMessageBox::warning( this, "Delete resource", tmp,
"Delete", "Cancel",
0, // Enter == button 0
1 ) ) { // Escape == button 1
case 0:
game->DeleteResource(restype,resnum);
select_resource_type(restype);
if(k>0)
list->setCurrentItem(k-1);
else
list->setCurrentItem(0);
break;
case 1:
break;
}
}
//**********************************************
void ResourcesWin::renumber_resource()
{
int k = list->currentItem();
if(k==-1)return;
AskNumber *ask_number = new AskNumber(0,0,"Resource number",
"Enter new resource number [0-255]: ");
if(!ask_number->exec())return;
QString str = ask_number->num->text();
int newnum = atoi((char *)str.latin1());
int restype = selected;
int resnum = ResourceIndex[k];
if(game->ResourceInfo[restype][newnum].Exists){
sprintf(tmp,"Resource %s.%d already exists. Replace it ?",ResTypeName[restype],newnum);
}
switch( QMessageBox::warning( this, "Renumber resource", tmp,
"Replace", "Cancel",
0, // Enter == button 0
1 ) ) { // Escape == button 1
case 0:
game->ReadResource(restype,resnum);
game->DeleteResource(restype,resnum);
game->AddResource(restype,newnum);
select_resource_type(restype);
break;
case 1:
break;
}
}
static QImage openBitmap( const char* title )
{
Q3FileDialog *f = new Q3FileDialog(0,"Load visible bitmap",true);
const char *filters[] = {"All files (*)",NULL};
f->setFilters(filters);
QImage pic;
f->setCaption(title);
f->setMode(Q3FileDialog::ExistingFile);
f->setDir(game->srcdir.c_str());
if ( f->exec() == QDialog::Accepted )
if ( !f->selectedFile().isEmpty() )
{
pic = QImage( f->selectedFile());
if ( pic.isNull())
menu->errmes("Error loading bitmap.");
}
if (!pic.isNull())
if ( (pic.width() != 320 && pic.width() != 160) || pic.height()<168 )
{
menu->errmes("Bitmap size must be 320x168 or 160x168.\nHeight can be more but will be cropped to 168.");
}
return pic;
}
//**********************************************
void ResourcesWin::import_resource()
{
QImage vis, pri;
vis = openBitmap("Open visible bitmap");
if ( vis.isNull())
return;
pri = openBitmap("Open PRIORITY bitmap (or press cancel)");
AskNumber *ask_number = new AskNumber(0,0,"Resource number",
"Enter new resource number [0-255]: ");
if(!ask_number->exec()) return;
QString str = ask_number->num->text();
int newnum = atoi((char *)str.latin1());
int restype = selected;
int replace = 0;
if(game->ResourceInfo[restype][newnum].Exists)
{
sprintf(tmp,"Resource %s.%d already exists. Replace it ?",ResTypeName[restype],newnum);
replace = QMessageBox::warning( this, "Overwrite resource", tmp, "Replace", "Cancel", 0, 1 );
}
switch( replace )
{
case 0:
{
if(game->ResourceInfo[restype][newnum].Exists)
game->DeleteResource(restype, newnum);
QByteArray res;
const char* err = bitmapToAGIPicture( vis, pri, &res );
if ( err )
{
menu->errmes(err);
return;
}
ResourceData.Size = res.size();
memcpy( ResourceData.Data, res.data(), res.size());
game->AddResource(restype, newnum); // uses data from ResourceData
select_resource_type(restype);
for ( int k=0; k<255; ++k )
if ( ResourceIndex[k] == newnum )
list->setSelected(k, true);
}
break;
case 1:
break;
}
}
//**********************************************
static void extract(char *filename,int restype,int resnum)
{
if(game->ReadResource(restype,resnum))return ;
FILE *fptr=fopen(filename,"wb");
if(fptr==NULL){
menu->errmes("Can't open file %s ! ",filename);
return ;
}
if(restype==LOGIC && game->save_logic_as_text){
Logic *logic = new Logic();
int err=logic->decode(resnum);
if(!err)fprintf(fptr,"%s",logic->OutputText.c_str());
delete logic;
}
else{
fwrite(ResourceData.Data,ResourceData.Size,1,fptr);
}
fclose(fptr);
}
//**********************************************
void ResourcesWin::extract_resource()
{
int restype = selected;
int k = list->currentItem();
int resnum = ResourceIndex[k];
Q3FileDialog *f = new Q3FileDialog(0,"Extract resource",true);
f->setCaption("Extract resource");
f->setMode(Q3FileDialog::AnyFile);
f->setDir(game->srcdir.c_str());
sprintf(tmp,"%s.%03d",ResTypeName[restype],resnum);
f->setSelection(tmp);
if ( f->exec() == QDialog::Accepted ) {
if ( !f->selectedFile().isEmpty() ){
extract((char *)f->selectedFile().latin1(),restype,resnum);
}
}
}
//**********************************************
void ResourcesWin::extract_all_resource()
{
char filename[256];
int restype = selected;
sprintf(tmp,"Do you really want to extract all %s resources ?",ResTypeName[restype]);
switch( QMessageBox::warning( this, "Extract all", tmp,
"Yes", "No",
0, // Enter == button 0
1 ) ) { // Escape == button 1
case 0:
break;
case 1:
return;
}
for(int resnum=0;resnum<256;resnum++){
if(game->ResourceInfo[restype][resnum].Exists){
sprintf(filename,"%s/%s.%03d",game->srcdir.c_str(),ResTypeName[restype],resnum);
extract(filename,restype,resnum);
}
}
}
//**********************************************
void ResourcesWin::add_resource()
{
Q3FileDialog *f = new Q3FileDialog(0,"Add resource",true);
static const char *types[6] = {"logic*.*","picture*.*","view*.*","sound*.*","All files (*)",NULL};
const char *filters[6];
switch(selected){
case LOGIC:
filters[0]=types[LOGIC];
filters[1]=types[PICTURE];
filters[2]=types[VIEW];
filters[3]=types[SOUND];
break;
case PICTURE:
filters[1]=types[LOGIC];
filters[0]=types[PICTURE];
filters[2]=types[VIEW];
filters[3]=types[SOUND];
break;
case VIEW:
filters[1]=types[LOGIC];
filters[2]=types[PICTURE];
filters[0]=types[VIEW];
filters[3]=types[SOUND];
break;
case SOUND:
filters[1]=types[LOGIC];
filters[2]=types[PICTURE];
filters[3]=types[VIEW];
filters[0]=types[SOUND];
break;
}
filters[4]=types[4];
filters[5]=NULL;
f->setFilters((const char **)filters);
f->setCaption("Add resource");
f->setMode(Q3FileDialog::ExistingFile);
f->setDir(game->srcdir.c_str());
if ( f->exec() == QDialog::Accepted ) {
if ( !f->selectedFile().isEmpty() ){
if(addmenu==NULL)addmenu = new AddResource(0,0,this);
addmenu->open((char *)f->selectedFile().latin1());
}
}
}
//**********************************************
void ResourcesWin::export_resource()
{
int k = list->currentItem();
if(k<0) return;
int i = ResourceIndex[k];
switch(selected) {
case SOUND:
if(game->ReadResource(SOUND,i))
menu->errmes("Couldn't read sound resource ! ");
else
showSaveAsMidi( this, ResourceData.Data );
break;
default:
qWarning("BUG in code. Export not supported for this resource type!");
break;
}
}
//**********************************************
AddResource::AddResource( QWidget *parent, const char *nam ,ResourcesWin *res )
: QWidget( parent, nam )
{
resources_win = res;
setCaption("Add resource");
Q3BoxLayout *box = new Q3VBoxLayout(this,10);
filename = new QLabel("Filename:",this);
// filename->setAutoResize(true); // TODO: REPLACE WITH A LAYOUT!
box->addWidget(filename);
Q3BoxLayout *box0 = new Q3HBoxLayout(box,4);
QLabel *lname = new QLabel("Name of resource:",this);
box0->addWidget(lname);
name = new QLabel("",this);
// name->setAutoResize(true); // TODO: REPLACE WITH A LAYOUT!
box0->addWidget(name);
type = new Q3ButtonGroup(4,Qt::Horizontal,"Type",this);
type->setExclusive(true);
QRadioButton *logic = new QRadioButton(type);
logic->setText("LOGIC");
logic->setChecked(true);
restype=0;
QRadioButton *picture = new QRadioButton(type);
picture->setText("PICTURE");
QRadioButton *view = new QRadioButton(type);
view->setText("VIEW");
QRadioButton *sound = new QRadioButton(type);
sound->setText("SOUND");
connect( type, SIGNAL(clicked(int)), SLOT(select_type(int)) );
box->addWidget(type);
Q3BoxLayout *box1 = new Q3HBoxLayout(box,10);
QLabel *lnumber = new QLabel("Number: [0-255]",this);
box1->addWidget(lnumber);
number = new QLineEdit(this);
number->setMinimumWidth(60);
connect( number, SIGNAL(textChanged(const QString &)), SLOT(edit_cb(const QString &)) );
box1->addWidget(number);
Q3BoxLayout *box2 = new Q3HBoxLayout(box,40);
QPushButton *ok = new QPushButton("OK",this);
connect( ok, SIGNAL(clicked()), SLOT(ok_cb()) );
box2->addWidget(ok);
QPushButton *cancel = new QPushButton("Cancel",this);
connect( cancel, SIGNAL(clicked()), SLOT(cancel_cb()) );
box2->addWidget(cancel);
}
//**********************************************
void AddResource::open(char *file_name)
{
char *ptr;
file = string(file_name);
if((ptr = strrchr(file_name,'/'))==NULL)ptr=file_name;
else ptr++;
sprintf(tmp,"Filename: %s",ptr);
filename->setText(tmp);
if(!strncasecmp(ptr,"logic",5)){
restype=LOGIC;
type->setButton(restype);
}
else if(!strncasecmp(ptr,"picture",7)){
restype=PICTURE;
type->setButton(restype);
}
else if(!strncasecmp(ptr,"view",4)){
restype=VIEW;
type->setButton(VIEW);
}
else if(!strncasecmp(ptr,"sound",5)){
restype=SOUND;
type->setButton(SOUND);
}
select_type(restype);
show();
}
//**********************************************
void AddResource::edit_cb(const QString &str)
{
int num = atoi((char *)str.latin1());
sprintf(tmp,"%s.%d",ResTypeName[restype],num);
name->setText(tmp);
}
//**********************************************
static int load_resource(const char *filename,int restype)
{
extern TStringList InputLines;
char *ptr;
byte b;
FILE *fptr = fopen(filename,"rb");
if(fptr==NULL){
menu->errmes("Can't open file %s ! ",filename);
return 1;
}
struct stat buf;
fstat(fileno(fptr),&buf);
int size=buf.st_size;
if(size >= MaxResourceSize){
menu->errmes("File %s is too big ! ",filename);
fclose(fptr);
return 1;
}
if(restype==LOGIC){
//check if file is binary or ascii
fread(ResourceData.Data,MIN(size,64),1,fptr);
for(int i=0;i<MIN(size,64);i++){
b=ResourceData.Data[i];
if(b>0x80||(b<0x20&&b!=0x0a&&b!=0x0d&&b!=0x09)){ //file is binary
fseek(fptr,0,SEEK_SET);
ResourceData.Size = size;
fread(ResourceData.Data,ResourceData.Size,1,fptr);
fclose(fptr);
return 0;
}
}
//file is ascii - trying to compile
fseek(fptr,0,SEEK_SET);
Logic *logic = new Logic();
InputLines.lfree();
while(fgets(tmp,1024,fptr)!=NULL){
if((ptr=strchr(tmp,0x0a)))*ptr=0;
if((ptr=strchr(tmp,0x0d)))*ptr=0;
InputLines.add(tmp);
}
fclose(fptr);
int err = logic->compile();
delete logic;
if(err)return 1;
}
else{
ResourceData.Size = size;
fread(ResourceData.Data,ResourceData.Size,1,fptr);
fclose(fptr);
}
return 0;
}
//**********************************************
void AddResource::ok_cb()
{
QString str = number->text();
int num = atoi((char *)str.latin1());
if(num<0||num>255){
menu->errmes("Resource number must be between 0 and 255 !");
return ;
}
if(game->ResourceInfo[restype][num].Exists){
sprintf(tmp,"Resource %s.%d already exists. Replace it ?",ResTypeName[restype],num);
switch( QMessageBox::warning( this, "Add resource", tmp,
"Replace", "Cancel",
0, // Enter == button 0
1 ) ) { // Escape == button 1
case 0:
if(!load_resource(file.c_str(),restype))
game->AddResource(restype,num);
break;
case 1:
break;
}
}
else{
if(!load_resource(file.c_str(),restype)){
game->AddResource(restype,num);
if( resources_win->selected == restype)
resources_win->select_resource_type(restype);
}
}
hide();
}
//**********************************************
void AddResource::cancel_cb()
{
hide();
}
//**********************************************
void AddResource::select_type(int type)
{
restype = type;
QString str = number->text();
int num = atoi((char *)str.latin1());
sprintf(tmp,"%s.%d",ResTypeName[restype],num);
name->setText(tmp);
}

110
src/resources.h Normal file
View File

@@ -0,0 +1,110 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef RESOURCES_H
#define RESOURCES_H
#include <string>
#include <qwidget.h>
#include <qlabel.h>
#include <q3listbox.h>
#include <qcombobox.h>
#include <qlayout.h>
#include <qlineedit.h>
#include <q3buttongroup.h>
//Added by qt3to4:
#include <QShowEvent>
#include <QHideEvent>
#include <QCloseEvent>
#include <Q3PopupMenu>
#include "preview.h"
class ResourcesWin;
class Preview;
class AddResource : public QWidget
{
Q_OBJECT
public:
AddResource( QWidget *parent=0, const char *name=0 , ResourcesWin *res=0);
QLabel *filename;
QLabel *name;
QLineEdit *number;
Q3ButtonGroup *type;
ResourcesWin *resources_win;
Preview *preview;
int restype;
string file;
void open(char *filename);
public slots:
void ok_cb();
void cancel_cb();
void select_type(int);
void edit_cb(const QString &);
};
class ResourcesWin : public QWidget
{
Q_OBJECT
public:
ResourcesWin( QWidget* parent = 0, const char* name=0, int winnum=0);
Q3ListBox *list;
int selected;
int ResourceNum;
Preview *preview;
unsigned char ResourceIndex[256];
bool closing;
public slots:
void select_resource_type( int i);
void highlight_resource( int i);
void select_resource( int i);
void set_current(int i);
void add_resource(void);
void extract_resource(void);
void extract_all_resource(void);
void delete_resource(void);
void renumber_resource(void);
void new_resource_window(void);
void export_resource(void);
void import_resource(void);
protected:
bool first;
QLabel *msg;
QComboBox *type;
QWidget *previewPane;
AddResource *addmenu;
Q3PopupMenu *resourceMenu;
int importMenuItemID;
int winnum;
void closeEvent( QCloseEvent *e );
void showEvent( QShowEvent * );
void hideEvent( QHideEvent * );
void deinit();
};
#endif

24
src/right.xpm Normal file
View File

@@ -0,0 +1,24 @@
/* XPM */
static const char *right[] = {
/* columns rows colors chars-per-pixel */
"16 16 2 1",
" c black",
". c gray100",
/* pixels */
"................",
"................",
".... ..........",
".... .........",
".... ........",
".... .......",
".... ......",
".... .....",
".... .....",
".... ......",
".... .......",
".... ........",
".... .........",
".... ..........",
"................",
"................"
};

24
src/right1.xpm Normal file
View File

@@ -0,0 +1,24 @@
/* XPM */
static const char *right1[] = {
/* columns rows colors chars-per-pixel */
"16 16 2 1",
" c black",
". c gray100",
/* pixels */
"................",
"................",
".... ........",
"..... .......",
"...... ......",
"....... .....",
"........ ....",
"......... ...",
"......... ...",
"........ ....",
"....... .....",
"...... ......",
"..... .......",
".... ........",
"................",
"................"
};

24
src/right1_x.xpm Normal file
View File

@@ -0,0 +1,24 @@
/* XPM */
static const char *right1_x[] = {
/* columns rows colors chars-per-pixel */
"16 16 2 1",
" c black",
". c None",
/* pixels */
"................",
"................",
".... ........",
"..... .......",
"...... ......",
"....... .....",
"........ ....",
"......... ...",
"......... ...",
"........ ....",
"....... .....",
"...... ......",
"..... .......",
".... ........",
"................",
"................"
};

24
src/right2.xpm Normal file
View File

@@ -0,0 +1,24 @@
/* XPM */
static const char *right2[] = {
/* columns rows colors chars-per-pixel */
"16 16 2 1",
" c black",
". c gray100",
/* pixels */
"................",
"................",
". ... ......",
".. ... .....",
"... ... ....",
".... ... ...",
"..... ... ..",
"...... ... .",
"...... ... .",
"..... ... ..",
".... ... ...",
"... ... ....",
".. ... .....",
". ... ......",
"................",
"................"
};

24
src/right2_x.xpm Normal file
View File

@@ -0,0 +1,24 @@
/* XPM */
static const char *right2_x[] = {
/* columns rows colors chars-per-pixel */
"16 16 2 1",
" c black",
". c None",
/* pixels */
"................",
"................",
". ... ......",
".. ... .....",
"... ... ....",
".... ... ...",
"..... ... ..",
"...... ... .",
"...... ... .",
"..... ... ..",
".... ... ...",
"... ... ....",
".. ... .....",
". ... ......",
"................",
"................"
};

24
src/right_x.xpm Normal file
View File

@@ -0,0 +1,24 @@
/* XPM */
static const char *right_x[] = {
/* columns rows colors chars-per-pixel */
"16 16 2 1",
" c black",
". c None",
/* pixels */
"................",
"................",
".... ..........",
".... .........",
".... ........",
".... .......",
".... ......",
".... .....",
".... .....",
".... ......",
".... .......",
".... ........",
".... .........",
".... ..........",
"................",
"................"
};

24
src/rightarrow_x.xpm Normal file
View File

@@ -0,0 +1,24 @@
/* XPM */
static const char *rightarrow_x[] = {
/* columns rows colors chars-per-pixel */
"16 16 2 1",
" c black",
". c None",
/* pixels */
"....... .......",
"....... ......",
"....... .....",
"....... ....",
"....... ...",
"....... ..",
". .",
". ",
". ",
". .",
"....... ..",
"....... ...",
"....... ....",
"....... .....",
"....... ......",
"....... ......."
};

916
src/roomgen.cpp Normal file
View File

@@ -0,0 +1,916 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
* The idea and most of the design of RoomGen module are copied from the
* "AGI Base Logic Generator" utility by Joel McCormick.
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include "logedit.h"
#include "game.h"
#include "menu.h"
#include "roomgen.h"
#include <string>
#include <stdio.h>
#include <sys/types.h>
#ifndef _WIN32
#include <dirent.h>
#include <unistd.h>
#endif
#include <sys/stat.h>
#include <stdlib.h>
#include <ctype.h>
#include <qapplication.h>
#include <q3filedialog.h>
#include <q3grid.h>
//Added by qt3to4:
#include <Q3HBoxLayout>
#include <Q3BoxLayout>
#include <Q3GridLayout>
#include <Q3Frame>
#include <QLabel>
#include <Q3VBoxLayout>
static const char *dirs[4] = {"left","right","bottom","horizon"};
//***********************************************
RoomGen::RoomGen( QWidget *parent, const char *name)
: QDialog( parent, name, true )
{
int i;
setCaption("AGI Base Logic Generator");
Q3BoxLayout *all = new Q3VBoxLayout(this,5);
Q3HBoxLayout *upper = new Q3HBoxLayout(all,10);
Q3Grid *gtxt = new Q3Grid( 2, this);
gtxt->setSpacing(4);
upper->addWidget(gtxt);
QLabel *llog = new QLabel("Logic Number:",gtxt);
llog=llog; //avoid compilation warning
lnum = new QLineEdit(gtxt);
lnum->setFixedWidth(40);
lnum->setText("0");
//lnum->selectAll();
connect(lnum,SIGNAL(textChanged(const QString &)),SLOT(lnum_cb()));
QLabel *lpic = new QLabel("Picture Number:",gtxt);
lpic=lpic;
pnum = new QLineEdit(gtxt);
pnum->setFixedWidth(40);
pnum->setText("0");
//pnum->selectAll();
QLabel *lhor = new QLabel("Horizon at Y:",gtxt);
lhor=lhor;
hnum = new QLineEdit(gtxt);
hnum->setFixedWidth(40);
hnum->setText("36");
//hnum->selectAll();
Q3VBoxLayout *check = new Q3VBoxLayout(upper,2);
draw_ego = new QCheckBox("Draw Ego initially",this);
draw_ego->setChecked(true);
check->addWidget(draw_ego);
first_room = new QCheckBox("First room",this);
connect(first_room,SIGNAL(clicked()),SLOT(first_room_cb()));
check->addWidget(first_room);
inc_def = new QCheckBox("Include defines.txt",this);
check->addWidget(inc_def);
inc_def->setChecked(true);
gen_comm = new QCheckBox("Generate comments",this);
gen_comm->setChecked(true);
check->addWidget(gen_comm);
Q3VBoxLayout *but = new Q3VBoxLayout(upper,2);
QPushButton *entry = new QPushButton("Entry and looking",this);
connect(entry,SIGNAL(clicked()),SLOT(entry_cb()));
but->addWidget(entry);
QPushButton *first = new QPushButton("First room controls",this);
connect(first,SIGNAL(clicked()),SLOT(first_cb()));
but->addWidget(first);
Q3BoxLayout *ledge = new Q3HBoxLayout(all,1);
// QGroupBox *ego_pos_b = new QGroupBox(1,Horizontal,"Ego Positioning (-1 = ignore)",this);
Q3Frame *ego_pos_b = new Q3Frame(this);
ego_pos_b->setFrameStyle( Q3Frame::Box | Q3Frame::Sunken );
ego_pos_b->setLineWidth(1);
ego_pos_b->setMargin(2);
Q3GridLayout *ego_pos = new Q3GridLayout(ego_pos_b,6,6,10,4);
QLabel *ll = new QLabel("Ego Positioning (-1 = ignore)",ego_pos_b);
ego_pos->addMultiCellWidget(ll,0,0,0,5,AlignCenter);
int row=1,col;
QLabel *l_from = new QLabel("Coming from",ego_pos_b);
ego_pos->addMultiCellWidget(l_from,row,row,0,1,AlignLeft);
QLabel *l_pos = new QLabel("Position Ego at",ego_pos_b);
ego_pos->addMultiCellWidget(l_pos,row,row,2,5,AlignCenter);
QLabel *l_lroom[4],*l_x[4],*l_y[4];
row++;
for(i=0;i<4;i++,row++){
col=0;
l_lroom[i] = new QLabel("room:",ego_pos_b);
ego_pos->addWidget(l_lroom[i],row,col,AlignRight); col++;
from[i] = new QLineEdit(ego_pos_b);
from[i]->setFixedWidth(40);
from[i]->setText("-1");
// from[i]->selectAll();
ego_pos->addWidget(from[i],row,col,AlignLeft); col++;
l_x[i] = new QLabel("X:",ego_pos_b);
ego_pos->addWidget(l_x[i],row,col,AlignRight); col++;
x[i] = new QLineEdit(ego_pos_b);
x[i]->setText("-1");
// x[i]->selectAll();
x[i]->setFixedWidth(40);
ego_pos->addWidget(x[i],row,col,AlignLeft); col++;
l_y[i] = new QLabel("Y:",ego_pos_b);
ego_pos->addWidget(l_y[i],row,col,AlignRight); col++;
y[i] = new QLineEdit(ego_pos_b);
y[i]->setText("-1");
// y[i]->selectAll();
y[i]->setFixedWidth(40);
ego_pos->addWidget(y[i],row,col,AlignLeft); col++;
}
QPushButton *ego_adv = new QPushButton("Advanced",ego_pos_b);
connect(ego_adv,SIGNAL(clicked()),SLOT(ego_advanced_cb()));
ego_pos->addMultiCellWidget(ego_adv,row,row,0,5,AlignCenter);
ledge->addWidget(ego_pos_b,1);
Q3Frame *edge_control_b = new Q3Frame(this);
edge_control_b->setFrameStyle( Q3Frame::Box | Q3Frame::Sunken );
edge_control_b->setLineWidth(1);
edge_control_b->setMargin(4);
Q3GridLayout *edge_control = new Q3GridLayout(edge_control_b,6,2,10,1);
QLabel *ll1 = new QLabel("Edge Controls (-1 = ignore)",edge_control_b);
edge_control->addMultiCellWidget(ll1,0,0,0,1,AlignCenter);
row=1;
col=0;
QLabel *l_if = new QLabel("If Ego touches:",edge_control_b);
edge_control->addWidget(l_if,row,col,AlignLeft); col++;
QLabel *l_goto = new QLabel("Goto Room:",edge_control_b);
edge_control->addWidget(l_goto,row,col,AlignCenter); col++;
row++;
QLabel *l_e[4];
const char *dirs[4] = {"Left Edge:","Right Edge:","Bottom Edge:","Horizon Edge:"};
for(i=0;i<4;i++,row++){
col=0;
l_e[i] = new QLabel(dirs[i],edge_control_b);
edge_control->addWidget(l_e[i],row,col,AlignLeft); col++;
edge[i] = new QLineEdit(edge_control_b);
edge[i]->setFixedWidth(40);
edge[i]->setText("-1");
// edge[i]->selectAll();
edge_control->addWidget(edge[i],row,col,AlignCenter); col++;
}
col=0;
QPushButton *edge_adv = new QPushButton("Advanced",edge_control_b);
connect(edge_adv,SIGNAL(clicked()),SLOT(edge_advanced_cb()));
edge_control->addMultiCellWidget(edge_adv,row,row,0,1,AlignCenter);
ledge->addWidget(edge_control_b,0);
Q3HBoxLayout *ltitle = new Q3HBoxLayout(all,4);
QLabel *lcom = new QLabel("Logic Title (for comments):",this);
ltitle->addWidget(lcom);
title = new QLineEdit(this);
ltitle->addWidget(title);
Q3HBoxLayout *last = new Q3HBoxLayout(all,20);
QPushButton *ok = new QPushButton("OK",this);
ok->setMaximumSize(80,40);
connect(ok,SIGNAL(clicked()),SLOT(ok_cb()));
last->addWidget(ok,AlignRight);
QPushButton *cancel = new QPushButton("Cancel",this);
cancel->setMaximumSize(80,40);
connect(cancel,SIGNAL(clicked()),SLOT(reject()));
last->addWidget(cancel,AlignLeft);
adjustSize();
room_entry = NULL;
room_first = NULL;
ego_advanced = NULL;
edge_advanced = NULL;
xa=ya=-1;
for(i=0;i<4;i++){
empty_e[i]=false;
display_e[i]=false;
e_mes[i]="You can't go that way.";
}
entry_mes="";
look_mes="";
status=input=true;
x1=y1=-1;
}
//************************************************
bool RoomGen::bad_int(QLineEdit *w,int *res,int nmin,int nmax,bool ignore,const char *text)
{
*res=-1;
QString str=w->text();
if(!str.isEmpty())
*res=atoi((char *)str.latin1());
if((*res==-1) && ignore)return false;
if((*res<nmin)||(*res>nmax)){
menu->errmes("%s must be between %d and %d !",text,nmin,nmax);
return true;
}
return false;
}
//************************************************
bool RoomGen::bad_int(int res,int nmin,int nmax,bool ignore,const char *text)
{
if(res==-1 && ignore)return false;
if(res<nmin||res>nmax){
menu->errmes("%s must be between %d and %d !",text,nmin,nmax);
return true;
}
return false;
}
//************************************************
bool RoomGen::bad_input()
{
QString str;
int i;
if(bad_int(lnum,&ln,0,255,false,"Logic number"))return true;
if(bad_int(pnum,&pn,0,255,false,"Picture number"))return true;
if(bad_int(hnum,&hn,0,167,false,"Horizon value"))return true;
for(i=0;i<4;i++){
rn[i]=xn[i]=yn[i]=-1;
str=from[i]->text();
if(!str.isEmpty())rn[i]=atoi((char *)str.latin1());
str=x[i]->text();
if(!str.isEmpty())xn[i]=atoi((char *)str.latin1());
str=y[i]->text();
if(!str.isEmpty())yn[i]=atoi((char *)str.latin1());
if(rn[i]==-1||xn[i]==-1||yn[i]==-1){
if(!(rn[i]==-1&&xn[i]==-1&&yn[i]==-1)){
menu->errmes("Ego positioning: incomplete input !");
return true;
}
}
else{
if(bad_int(rn[i],0,255,false,"Ego positioning:\nRoom number"))return true;
if(bad_int(xn[i],0,319,false,"Ego positioning:\nX"))return true;
if(bad_int(yn[i],0,167,false,"Ego positioning:\nY"))return true;
}
}
for(i=0;i<4;i++){
if(bad_int(edge[i],&en[i],0,255,true,"Edge controls:\nroom number"))return true;
}
if(!(xa==-1&&ya==-1)){
if(bad_int(xa,0,319,false,"Unconditional Ego positioning:\nX"))return true;
if(bad_int(ya,0,167,false,"Unconditional Ego positioning:\nY"))return true;
}
if(!(x1==-1&&y1==-1)){
if(bad_int(x1,0,319,false,"First room Ego positioning:\nX"))return true;
if(bad_int(y1,0,167,false,"First room Ego positioning:\nY"))return true;
}
return false;
}
//************************************************
void RoomGen::ok_cb()
{
int i,k;
int level=0;
if(bad_input())return;
bool com=gen_comm->isChecked();
text="// ****************************************************************\n\
//\n";
QString str=title->text();
if(str.isEmpty()){
sprintf(tmp,"// Logic %d\n",ln);
}
else{
sprintf(tmp,"// Logic %d: %s\n",ln,str.latin1());
}
text+=tmp;
text+="// \n// ****************************************************************\n";
if(inc_def->isChecked()){
text+="#include \"defines.txt\"\n";
}
text+="if (new_room) {\n";
if(ln==pn){
text+=" load.pic(room_no);\n\
draw.pic(room_no);\n\
discard.pic(room_no);\n";
}
else{
sprintf(tmp," v255=%d;\n",pn);
text+=tmp;
text+=" load.pic(v255);\n\
draw.pic(v255);\n\
discard.pic(v255);\n";
}
if(com)text+=" //ADD ADDITIONAL INITIALIZATION CODE HERE\n";
if(hn!=36){
sprintf(tmp," set.horizon(%d);\n",hn);
text+=tmp;
}
if(first_room->isChecked()){
text+=" if ((prev_room_no == 0 || prev_room_no == 1)){\n";
if(com)text+=" //THIS IS THE FIRST ROOM, ADD ANY ONE-TIME INITIALIZATION HERE\n";
if(x1!=-1){
sprintf(tmp," position(ego, %d, %d);\n",x1,y1);
text+=tmp;
}
if(status)text+=" status.line.on();\n";
if(input)text+=" accept.input();\n";
text+=" }\n";
level++;
}
for(i=0;i<4;i++){
if(rn[i]==-1)continue;
if(level){
for(k=0;k<level;k++){
text+=" ";
}
text+="else {\n";
}
for(k=0;k<level;k++){
text+=" ";
}
sprintf(tmp," if (prev_room_no == %d){\n",rn[i]);
text+=tmp;
for(k=0;k<level;k++){
text+=" ";
}
sprintf(tmp," position(ego, %d, %d);\n",xn[i],yn[i]);
text+=tmp;
for(k=0;k<level;k++){
text+=" ";
}
text+=" }\n";
level++;
}
if(xa!=-1){
if(level){
for(k=0;k<level;k++){
text+=" ";
}
text+="else {\n";
}
for(k=0;k<level;k++){
text+=" ";
}
sprintf(tmp," position(ego, %d, %d);\n",xa,ya);
text+=tmp;
if(level){
for(k=0;k<level;k++){
text+=" ";
}
text+="}\n";
}
}
for(i=level-1;i>0;i--){
for(k=0;k<i;k++){
text+=" ";
}
text+="}\n";
}
if(draw_ego->isChecked()){
text+=" draw(ego);\n";
}
text+=" show.pic();\n";
if(entry_mes.length()>0){
sprintf(tmp," print(\"%s\");\n",entry_mes.c_str());
text+=tmp;
}
text+="}\n";
for(i=0;i<4;i++){
if(en[i]==-1){
if(display_e[i]){
sprintf(tmp,"if (ego_edge_code == %s_edge){\n",dirs[i]);
text+=tmp;
sprintf(tmp," print(\"%s\");\n",e_mes[i].c_str());
text+=tmp;
text+=" ego_dir = 0;\n}\n";
}
else if(empty_e[i]){
sprintf(tmp,"if (ego_edge_code == %s_edge){\n",dirs[i]);
text+=tmp;
if(com){
sprintf(tmp," //ADD EGO-TOUCHING-%s CODE HERE\n",dirs[i]);
text+=tmp;
}
sprintf(tmp,"}\n");
text+=tmp;
}
}
else{
sprintf(tmp,"if (ego_edge_code == %s_edge){\n",dirs[i]);
text+=tmp;
if(com){
sprintf(tmp," //ADD ADDITIONAL %s EXIT CODE HERE\n",dirs[i]);
text+=tmp;
}
sprintf(tmp," new.room(%d);\n}\n",en[i]);
text+=tmp;
}
}
text+="if (input_recieved && unknown_word_no == 0 && !input_parsed) {\n";
if(look_mes.length()>0){
text += " if (said(\"look\")){\n";
sprintf(tmp," print(\"%s\");\n }\n",look_mes.c_str());
text+=tmp;
}
text +="}\n\nreturn();\n";
done(Accepted);
}
//************************************************
void RoomGen::ego_advanced_cb()
{
if(ego_advanced==NULL)ego_advanced = new RoomGenPos();
sprintf(tmp,"%d",xa);
ego_advanced->x->setText(tmp);
sprintf(tmp,"%d",ya);
ego_advanced->y->setText(tmp);
if(ego_advanced->exec()){
xa=atoi((char *)ego_advanced->x->text().latin1());
ya=atoi((char *)ego_advanced->y->text().latin1());
}
}
//************************************************
void RoomGen::edge_advanced_cb()
{
int i;
if(edge_advanced==NULL)edge_advanced = new RoomGenEdge();
for(i=0;i<4;i++){
edge_advanced->c_edge[i]->setChecked(empty_e[i]);
edge_advanced->m_edge[i]->setChecked(display_e[i]);
edge_advanced->e_mes[i]=e_mes[i];
}
if(edge_advanced->exec()){
for(i=0;i<4;i++){
empty_e[i]=edge_advanced->c_edge[i]->isChecked();
display_e[i]=edge_advanced->m_edge[i]->isChecked();
if(display_e[i]){
e_mes[i]=edge_advanced->e_mes[i];
}
}
}
}
//************************************************
void RoomGen::entry_cb()
{
if(room_entry==NULL)room_entry = new RoomGenEntry();
room_entry->entry_text->setText(entry_mes.c_str());
room_entry->look_text->setText(look_mes.c_str());
if(room_entry->exec()){
entry_mes=room_entry->entry_text->text().latin1();
look_mes=room_entry->look_text->text().latin1();
}
}
//************************************************
void RoomGen::first_room_cb()
{
if(first_room->isChecked()){
first_cb();
}
}
//************************************************
void RoomGen::first_cb()
{
if(room_first==NULL)room_first = new RoomGenFirst();
room_first->status->setChecked(status);
room_first->input->setChecked(input);
sprintf(tmp,"%d",x1);
room_first->x->setText(tmp);
sprintf(tmp,"%d",y1);
room_first->y->setText(tmp);
if(room_first->exec()){
status=room_first->status->isChecked();
input=room_first->input->isChecked();
x1=atoi((char *)room_first->x->text().latin1());
y1=atoi((char *)room_first->y->text().latin1());
}
}
//************************************************
void RoomGen::lnum_cb()
{
pnum->setText(lnum->text());
}
//************************************************
RoomGenEntry::RoomGenEntry( QWidget *parent, const char *name)
: QDialog( parent, name, true )
{
setCaption("Room Entry and Looking");
Q3BoxLayout *all = new Q3VBoxLayout(this,5);
QLabel *entry = new QLabel("On room entry:",this);
all->addWidget(entry);
Q3BoxLayout *l1 = new Q3HBoxLayout(all,1);
QLabel *print1 = new QLabel("print(\"",this);
l1->addWidget(print1);
entry_text = new QLineEdit(this);
entry_text->setMinimumWidth(300);
l1->addWidget(entry_text);
QLabel *print11 = new QLabel("\");",this);
l1->addWidget(print11);
QLabel *ifsaid = new QLabel("if said(\"look\")){",this);
all->addWidget(ifsaid);
QWidget *place = new QWidget(this);
Q3BoxLayout *l2 = new Q3HBoxLayout(place,1);
QLabel *print2 = new QLabel("print(\"",place);
l2->addWidget(print2);
look_text = new QLineEdit(place);
look_text->setMinimumWidth(300);
l2->addWidget(look_text);
QLabel *print22 = new QLabel("\");",place);
l2->addWidget(print22);
all->addWidget(place);
QLabel *p = new QLabel("}",this);
all->addWidget(p);
Q3BoxLayout *last = new Q3HBoxLayout(all,10);
QPushButton *ok = new QPushButton("OK",this);
ok->setMaximumSize(80,40);
connect(ok,SIGNAL(clicked()),SLOT(accept()));
last->addWidget(ok,AlignRight);
QPushButton *cancel = new QPushButton("Cancel",this);
cancel->setMaximumSize(80,40);
connect(cancel,SIGNAL(clicked()),SLOT(reject()));
last->addWidget(cancel,AlignLeft);
adjustSize();
}
//************************************************
RoomGenFirst::RoomGenFirst( QWidget *parent, const char *name)
: QDialog( parent, name, true )
{
setCaption("Controls for First Room");
Q3BoxLayout *all = new Q3VBoxLayout(this,5);
QLabel *egopos = new QLabel("Ego positioning (-1 = ignore)",this);
all->addWidget(egopos);
Q3GridLayout *l1 = new Q3GridLayout(all,6,1,5);
QLabel *lx = new QLabel("X:",this);
l1->addWidget(lx,0,0,AlignRight);
x = new QLineEdit(this);
x->setFixedWidth(40);
x->setText("-1");
x->selectAll();
l1->addWidget(x,0,1,AlignLeft);
QLabel *ly = new QLabel("Y:",this);
l1->addWidget(ly,0,2,AlignRight);
y = new QLineEdit(this);
y->setFixedWidth(40);
y->setText("-1");
y->selectAll();
l1->addWidget(y,0,3,AlignLeft);
QLabel *place = new QLabel(" ",this);
l1->addWidget(place,0,4,AlignCenter);
l1->setColStretch(4,1);
status = new QCheckBox("Turn on the status bar",this);
status->setChecked(true);
all->addWidget(status);
input = new QCheckBox("Accept player input",this);
input->setChecked(true);
all->addWidget(input);
Q3BoxLayout *last = new Q3HBoxLayout(all,10);
QPushButton *ok = new QPushButton("OK",this);
ok->setMaximumSize(80,40);
connect(ok,SIGNAL(clicked()),SLOT(accept()));
last->addWidget(ok,AlignRight);
QPushButton *cancel = new QPushButton("Cancel",this);
cancel->setMaximumSize(80,40);
connect(cancel,SIGNAL(clicked()),SLOT(reject()));
last->addWidget(cancel,AlignLeft);
adjustSize();
}
//************************************************
RoomGenPos::RoomGenPos( QWidget *parent, const char *name)
: QDialog( parent, name, true )
{
setCaption("Controls for First Room");
Q3BoxLayout *all = new Q3VBoxLayout(this,5);
QLabel *l = new QLabel("Absolute (Unconditional) Position:",this);
all->addWidget(l);
Q3GridLayout *l1 = new Q3GridLayout(all,6,1,5);
QLabel *lx = new QLabel("X:",this);
l1->addWidget(lx,0,0,AlignRight);
x = new QLineEdit(this);
x->setFixedWidth(40);
x->setText("-1");
x->selectAll();
l1->addWidget(x,0,1,AlignLeft);
QLabel *ly = new QLabel("Y:",this);
l1->addWidget(ly,0,2,AlignRight);
y = new QLineEdit(this);
y->setFixedWidth(40);
y->setText("-1");
y->selectAll();
l1->addWidget(y,0,3,AlignLeft);
QLabel *place = new QLabel(" ",this);
l1->addWidget(place,0,4,AlignCenter);
l1->setColStretch(4,1);
QLabel *com = new QLabel(
"Unconditional positioning is useful for positioning ego\n\
in the same place no matter what room it comes from.\n\
It can be used in conjunction with conditional positioning\n\
and the tp command in debug mode to position ego in a place\n\
where you won't get stuck behind control lines, etc."
,this);
all->addWidget(com);
Q3BoxLayout *last = new Q3HBoxLayout(all,10);
QPushButton *ok = new QPushButton("OK",this);
ok->setMaximumSize(80,40);
connect(ok,SIGNAL(clicked()),SLOT(accept()));
last->addWidget(ok,AlignRight);
QPushButton *cancel = new QPushButton("Cancel",this);
cancel->setMaximumSize(80,40);
connect(cancel,SIGNAL(clicked()),SLOT(reject()));
last->addWidget(cancel,AlignLeft);
adjustSize();
}
//************************************************
RoomGenEdge::RoomGenEdge( QWidget *parent, const char *name)
: QDialog( parent, name, true )
{
int i;
setCaption("Edge Code Advanced Controls");
Q3BoxLayout *all = new Q3VBoxLayout(this,5);
QLabel *com = new QLabel(
"It may be desirable to have an edge code that does not lead to different room.\n\
For example, you may wish to have the game print a message instead, as:\n\
\n\
if (ego_edge_code == horizon_edge){\n\
print(\"You cannot go that way.\");\n\
ego_dir = 0;\n\
}"
,this);
all->addWidget(com);
Q3GroupBox *edge = new Q3GroupBox(2,Horizontal,"Empty edge controls",this);
for(i=0;i<4;i++){
sprintf(tmp,"Include empty code for %s edge",dirs[i]);
c_edge[i]=new QCheckBox(tmp,edge);
}
all->addWidget(edge);
Q3GroupBox *messages = new Q3GroupBox(4,Horizontal,
"Messages (if Display is not checked, message will be ignored)",this);
for(i=0;i<4;i++){
m_edge[i] = new QCheckBox("Display",messages);
b_edge[i] = new QPushButton(messages);
sprintf(tmp,"message for %s edge",dirs[i]);
b_edge[i]->setText(tmp);
switch(i){
case 0:
connect(b_edge[i],SIGNAL(clicked()),SLOT(left_message())); break;
case 1:
connect(b_edge[i],SIGNAL(clicked()),SLOT(right_message())); break;
case 2:
connect(b_edge[i],SIGNAL(clicked()),SLOT(bot_message())); break;
case 3:
connect(b_edge[i],SIGNAL(clicked()),SLOT(hor_message())); break;
}
}
all->addWidget(messages);
Q3BoxLayout *last = new Q3HBoxLayout(all,10);
QPushButton *ok = new QPushButton("OK",this);
ok->setMaximumSize(80,40);
connect(ok,SIGNAL(clicked()),SLOT(accept()));
last->addWidget(ok,AlignRight);
QPushButton *cancel = new QPushButton("Cancel",this);
cancel->setMaximumSize(80,40);
connect(cancel,SIGNAL(clicked()),SLOT(reject()));
last->addWidget(cancel,AlignLeft);
adjustSize();
message=NULL;
}
void RoomGenEdge::left_message()
{
if(message==NULL)message = new RoomGenMessage();
message->name("Left",e_mes[0].c_str());
if(message->exec()){
e_mes[0] = (char *)message->message->text().latin1();
}
}
void RoomGenEdge::right_message()
{
if(message==NULL)message = new RoomGenMessage();
message->name("Right",e_mes[1].c_str());
if(message->exec()){
e_mes[1] = (char *)message->message->text().latin1();
}
}
void RoomGenEdge::bot_message()
{
if(message==NULL)message = new RoomGenMessage();
message->name("Bottom",e_mes[2].c_str());
if(message->exec()){
e_mes[2] = (char *)message->message->text().latin1();
}
}
void RoomGenEdge::hor_message()
{
if(message==NULL)message = new RoomGenMessage();
message->name("Horizon",e_mes[3].c_str());
if(message->exec()){
e_mes[3] = (char *)message->message->text().latin1();;
}
}
//************************************************
RoomGenMessage::RoomGenMessage( QWidget *parent, const char *name)
: QDialog( parent, name, true )
{
Q3BoxLayout *all = new Q3VBoxLayout(this,5);
l = new QLabel("",this);
//l->setAutoResize(true); // TODO: REPLACE WITH A LAYOUT!
all->addWidget(l);
message = new QLineEdit(this);
all->addWidget(message);
Q3BoxLayout *last = new Q3HBoxLayout(all,10);
QPushButton *ok = new QPushButton("OK",this);
ok->setMaximumSize(80,40);
connect(ok,SIGNAL(clicked()),SLOT(accept()));
last->addWidget(ok,AlignRight);
QPushButton *cancel = new QPushButton("Cancel",this);
cancel->setMaximumSize(80,40);
connect(cancel,SIGNAL(clicked()),SLOT(reject()));
last->addWidget(cancel,AlignLeft);
adjustSize();
}
void RoomGenMessage::name(const char *title,const char *text)
{
sprintf(tmp,"%s Message",title);
setCaption(tmp);
sprintf(tmp,"Enter a message to display when ego\ntouches %c%s edge:",tolower(title[0]),title+1);
l->setText(tmp);
message->setText(text);
message->selectAll();
}

148
src/roomgen.h Normal file
View File

@@ -0,0 +1,148 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
* The idea and most of the design of RoomGen module are copied from the
* "AGI Base Logic Generator" utility by Joel McCormick.
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef ROOMGEN_H
#define ROOMGEN_H
#include <qwidget.h>
#include <qlabel.h>
#include <qpushbutton.h>
#include <qlayout.h>
#include <qnamespace.h>
#include <qmessagebox.h>
#include <q3multilineedit.h>
#include <qevent.h>
#include <qstatusbar.h>
#include <qcheckbox.h>
#include "util.h"
#include "wutil.h"
#include "logic.h"
class RoomGenEntry: public QDialog
{
Q_OBJECT
public:
RoomGenEntry( QWidget *parent=0, const char *name=0 );
QLineEdit *entry_text,*look_text;
};
class RoomGenFirst: public QDialog
{
Q_OBJECT
public:
RoomGenFirst( QWidget *parent=0, const char *name=0 );
QLineEdit *x,*y;
QCheckBox *status,*input;
};
class RoomGenPos: public QDialog
{
Q_OBJECT
public:
RoomGenPos( QWidget *parent=0, const char *name=0 );
QLineEdit *x,*y;
};
class RoomGenMessage: public QDialog
{
Q_OBJECT
public:
RoomGenMessage( QWidget *parent=0, const char *name=0);
void name(const char *title, const char *text);
QLabel *l;
QLineEdit *message;
};
class RoomGenEdge: public QDialog
{
Q_OBJECT
public:
RoomGenEdge( QWidget *parent=0, const char *name=0 );
QCheckBox *c_edge[4];
QCheckBox *m_edge[4];
QPushButton *b_edge[4];
RoomGenMessage *message;
string e_mes[4];
public slots:
void left_message();
void right_message();
void bot_message();
void hor_message();
};
class RoomGen: public QDialog
{
Q_OBJECT
public:
RoomGen( QWidget *parent=0, const char *name=0 );
RoomGenEntry *room_entry;
RoomGenFirst *room_first;
RoomGenPos *ego_advanced;
RoomGenEdge *edge_advanced;
QLineEdit *lnum,*pnum,*hnum;
QCheckBox *draw_ego,*first_room,*inc_def,*gen_comm;
QLineEdit *from[4],*x[4],*y[4];
QLineEdit *edge[4];
QLineEdit *title;
string text;
bool incomplete_input();
int rn[4],xn[4],yn[4]; //coming from room rn, position ego at xn,yn
int en[4]; //edge controls (goto room)
int ln,pn; //logic number, picture number
int hn; //horizon
int xa,ya; //absolute (unconditional) position
int x1,y1; //first room ego position
bool empty_e[4]; //add empty edge controls
bool display_e[4]; //display edge messages
string e_mes[4]; //edge messages
string entry_mes,look_mes; //room entry & look messages
bool status,input; //1st room - status bar, player input
bool bad_int(QLineEdit *w,int *res,int nmin,int nmax,bool ignore,const char *text);
bool bad_int(int res,int nmin,int nmax,bool ignore,const char *text);
bool bad_input();
public slots:
void ego_advanced_cb();
void edge_advanced_cb();
void entry_cb();
void first_cb();
void ok_cb();
void lnum_cb();
void first_room_cb();
};
#endif

201
src/toolbar_close.xpm Normal file
View File

@@ -0,0 +1,201 @@
/* XPM */
static const char *toolbar_close[] = {
/* columns rows colors chars-per-pixel */
"24 24 171 2",
" c black",
". c #A4A400001F1F",
"X c #A8A800001E1E",
"o c #AAAA00001E1E",
"O c #AFAF00001B1B",
"+ c #ACAC00001D1D",
"@ c #B0B000001B1B",
"# c #B2B200001B1B",
"$ c #B0B000001C1C",
"% c #B5B500001A1A",
"& c #B6B600001919",
"* c #B6B600001A1A",
"= c #B5B505051F1F",
"- c #BCBC00001717",
"; c #BEBE00001616",
": c #BEBE01011717",
"> c #B8B800001919",
", c #B9B902021A1A",
"< c #BABA00001818",
"1 c #BBBB00001818",
"2 c #BDBD02021A1A",
"3 c #A2A200002020",
"4 c #B5B509092323",
"5 c #BABA0C0C2323",
"6 c #B9B90D0D2424",
"7 c #BBBB0D0D2424",
"8 c #BEBE0A0A2020",
"9 c #BFBF0E0E2424",
"0 c #C1C100001515",
"q c #C1C100001616",
"w c #C4C400001414",
"e c #C7C702021414",
"r c #C0C005051B1B",
"t c #C0C006061B1B",
"y c #C4C403031818",
"u c #C8C800001212",
"i c #C9C900001313",
"p c #C9C901011313",
"a c #CBCB02021515",
"s c #CCCC02021313",
"d c #CECE00001111",
"f c #CDCD05051616",
"g c #CECE06061616",
"h c #C8C80A0A1E1E",
"j c #CCCC09091A1A",
"k c #CCCC0B0B1E1E",
"l c #D1D101011010",
"z c #D1D102021111",
"x c #D0D003031414",
"c c #D5D502021010",
"v c #D1D10C0C1D1D",
"b c #D4D40A0A1919",
"n c #D9D902021010",
"m c #D8D804041111",
"M c #D8D804041212",
"N c #DBDB04041111",
"B c #DEDE07071212",
"V c #D9D908081414",
"C c #DFDF09091515",
"Z c #DADA0C0C1919",
"A c #DCDC0C0C1919",
"S c #D3D310101F1F",
"D c #DADA13131E1E",
"F c #DCDC10101B1B",
"G c #DDDD11111D1D",
"H c #C1C10E0E2424",
"J c #C3C30F0F2525",
"K c #C5C50E0E2020",
"L c #C5C512122626",
"P c #C9C910102222",
"I c #C9C913132626",
"U c #C8C814142626",
"Y c #CDCD11112222",
"T c #CDCD13132525",
"R c #CFCF16162727",
"E c #D3D312122020",
"W c #D0D016162727",
"Q c #D3D316162525",
"! c #D7D718182626",
"~ c #D2D218182929",
"^ c #D5D51A1A2828",
"/ c #DADA19192626",
"( c #DEDE18182424",
") c #DFDF19192424",
"_ c #D9D91B1B2828",
"` c #DCDC1F1F2B2B",
"' c #DFDF1F1F2929",
"] c #DFDF21212C2C",
"[ c #E7E704040D0D",
"{ c #E3E30A0A1313",
"} c #E1E10B0B1515",
"| c #E4E40D0D1515",
" . c #E7E70F0F1717",
".. c #EEEE0C0C1414",
"X. c #E4E411111B1B",
"o. c #E6E612121A1A",
"O. c #E9E917171E1E",
"+. c #ECEC12121A1A",
"@. c #ECEC15151C1C",
"#. c #EFEF17171C1C",
"$. c #F0F006060B0B",
"%. c #F2F21A1A1D1D",
"&. c #E1E118182323",
"*. c #E1E11F1F2929",
"=. c #E8E818182020",
"-. c #EAEA1F1F2626",
";. c #ECEC1E1E2525",
":. c #E8E81F1F2828",
">. c #F0F01D1D2323",
",. c #F1F11D1D2222",
"<. c #E2E222222B2B",
"1. c #E5E522222B2B",
"2. c #E5E524242C2C",
"3. c #E6E625252D2D",
"4. c #EEEE21212727",
"5. c #EEEE26262D2D",
"6. c #E7E728283030",
"7. c #EAEA2A2A3131",
"8. c #ECEC28283030",
"9. c #ECEC29293030",
"0. c #F5F520202323",
"q. c #F5F523232727",
"w. c #F3F325252929",
"e. c #F2F225252A2A",
"r. c #F0F027272C2C",
"t. c #F6F625252929",
"y. c #F7F72B2B2E2E",
"u. c #F9F928282B2B",
"i. c #F8F82C2C2D2D",
"p. c #FAFA2D2D2F2F",
"a. c #F0F02D2D3333",
"s. c #F3F32D2D3232",
"d. c #F5F52E2E3232",
"f. c #F4F431313535",
"g. c #F4F433333737",
"h. c #F5F536363939",
"j. c #F6F636363838",
"k. c #F6F636363A3A",
"l. c #F7F737373A3A",
"z. c #F6F638383B3B",
"x. c #FAFA31313333",
"c. c #FAFA32323434",
"v. c #F8F834343737",
"b. c #F9F934343737",
"n. c #FBFB36363737",
"m. c #FCFC33333434",
"M. c #FBFB39393B3B",
"N. c #F9F93B3B3D3D",
"B. c #FBFB3B3B3D3D",
"V. c #FCFC39393B3B",
"C. c #FCFC3C3C3D3D",
"Z. c #FDFD3F3F3F3F",
"A. c #FCFC3F3F4141",
"S. c #FBFB40404141",
"D. c #FCFC42424343",
"F. c #FDFD43434343",
"G. c #FEFE41414242",
"H. c #FEFE42424343",
"J. c #FDFD44444545",
"K. c #FDFD45454646",
"L. c #FDFD46464646",
"P. c #FDFD46464747",
"I. c #FEFE44444545",
"U. c #FEFE45454646",
"Y. c #FEFE46464747",
"T. c #FDFD47474848",
"R. c #FEFE47474848",
"E. c #FDFD48484949",
"W. c #FEFE48484848",
"Q. c gray100",
"!. c None",
/* pixels */
"!.!.!.!.!.!.!.!.!.!.!.!.!.!.!.!.!.!.!.!.!.!.!.!.",
"!.!.!.!.!. !.!.!.!.!.!.!.!.!.!.!.!. !.!.!.!.!.",
"!.!.!.!. H. !.!.!.!.!.!.!.!.!.!. $. !.!.!.!.",
"!.!.!. Y.Q.H. !.!.!.!.!.!.!.!. ..Q.[ !.!.!.",
"!.!. T.Q.Y.Y.Y. !.!.!.!.!.!. @.Q.C B n !.!.",
"!. T.Q.T.T.T.T.T. !.!.!.!. 4.Q.F b f p s !.",
"!.!. T.T.W.T.W.W.W. !.!. s.Q.) S h r 2 !.!.",
"!.!.!. W.T.T.T.T.T.Y. k.Q.1./ I 2 4 !.!.!.",
"!.!.!.!. Y.Y.Y.T.Y.Y.Z.N.h.9.' ~ H 4 !.!.!.!.",
"!.!.!.!.!. Y.I.H.D.A.B.k.9.3./ U 6 !.!.!.!.!.",
"!.!.!.!.!.!. H.Z.C.M.b.d.5.] Q L !.!.!.!.!.!.",
"!.!.!.!.!.!.!. M.b.x.y.w.-.( Y !.!.!.!.!.!.!.",
"!.!.!.!.!.!.!. m.p.u.q.;.O.D k !.!.!.!.!.!.!.",
"!.!.!.!.!.!. c.p.t.0.%.@.o.Z j 2 !.!.!.!.!.!.",
"!.!.!.!.!. h.Q.w.;.@.+. .} V f y < !.!.!.!.!.",
"!.!.!.!. k.Q.w.;.@.o. .{ B M x p 2 < !.!.!.!.",
"!.!.!. l.Q.8.:.&.G A M m d s 0 < & !.!.!.",
"!.!. k.Q.7.] / E v !.!. d d p 0 < & # !.!.",
"!. f.Q.6.] ! T K !.!.!.!. p w ; & # O . !.",
"!.!. 3.] ~ U 9 !.!.!.!.!.!. ; & O . . !.!.",
"!.!.!. T L 6 !.!.!.!.!.!.!.!. % . 3 !.!.!.",
"!.!.!.!. 6 !.!.!.!.!.!.!.!.!.!. 3 !.!.!.!.",
"!.!.!.!.!. !.!.!.!.!.!.!.!.!.!.!.!. !.!.!.!.!.",
"!.!.!.!.!.!.!.!.!.!.!.!.!.!.!.!.!.!.!.!.!.!.!.!."
};

124
src/toolbar_logedit.xpm Normal file
View File

@@ -0,0 +1,124 @@
/* XPM */
static const char *toolbar_logedit[] = {
/* columns rows colors chars-per-pixel */
"24 24 94 2",
" c black",
". c #000000007F7F",
"X c #7F7F00007F7F",
"o c #7F7F7F7F0000",
"O c navy",
"+ c #000000008181",
"@ c #000000008282",
"# c #000000008383",
"$ c #000000008989",
"% c #000000008A8A",
"& c #000000008F8F",
"* c #000000009090",
"= c #000000009292",
"- c #000000009898",
"; c #000000009B9B",
": c #00000000A6A6",
"> c #00000000B2B2",
", c #00000000B4B4",
"< c #00000000BCBC",
"1 c #00000000BFBF",
"2 c #00000000C0C0",
"3 c #00000000C5C5",
"4 c #00000000C6C6",
"5 c #00000000C9C9",
"6 c #00000000CCCC",
"7 c MediumBlue",
"8 c #00000000D1D1",
"9 c #00000000D3D3",
"0 c red",
"q c yellow",
"w c #BCBCBCBCBCBC",
"e c gray74",
"r c gray",
"t c gray75",
"y c #C0C0C0C0C0C0",
"u c #C1C1C1C1C1C1",
"i c gray76",
"p c #C3C3C3C3C3C3",
"a c gray77",
"s c #C5C5C5C5C5C5",
"d c gray78",
"f c #C8C8C8C8C8C8",
"g c gray79",
"h c #CACACACACACA",
"j c gray80",
"k c #CDCDCDCDCDCD",
"l c gray81",
"z c #D0D0D0D0D0D0",
"x c gray82",
"c c #D2D2D2D2D2D2",
"v c LightGray",
"b c gray83",
"n c #D5D5D5D5D5D5",
"m c gray84",
"M c #D7D7D7D7D7D7",
"N c #D8D8D8D8D8D8",
"B c gray85",
"V c #DADADADADADA",
"C c gray86",
"Z c gainsboro",
"A c #DDDDDDDDDDDD",
"S c gray87",
"D c #DFDFDFDFDFDF",
"F c #E1E1E1E1E1E1",
"G c #E2E2E2E2E2E2",
"H c gray89",
"J c #E4E4E4E4E4E4",
"K c gray90",
"L c #E6E6E6E6E6E6",
"P c #E7E7E7E7E7E7",
"I c gray91",
"U c #E9E9E9E9E9E9",
"Y c #EAEAEAEAEAEA",
"T c gray92",
"R c #ECECECECECEC",
"E c gray93",
"W c #EEEEEEEEEEEE",
"Q c #EFEFEFEFEFEF",
"! c gray94",
"~ c #F1F1F1F1F1F1",
"^ c gray95",
"/ c #F3F3F3F3F3F3",
"( c #F4F4F4F4F4F4",
") c gray96",
"_ c #F6F6F6F6F6F6",
"` c gray97",
"' c #F8F8F8F8F8F8",
"] c #F9F9F9F9F9F9",
"[ c gray98",
"{ c #FBFBFBFBFBFB",
"} c gray99",
"| c #FDFDFDFDFDFD",
" . c #FEFEFEFEFEFE",
".. c gray100",
/* pixels */
"t t t t t t t t t t t t t t t t t t t t t t t t ",
"t ",
"t q o q 9 8 ..5 1 , ..; = % ....@ ..@ ....... ",
"t o q 0 8 6 ..1 , ..; ..% ..@ @ . ... ... . . ",
"t q o 0 6 3 ..> : ..= ..@ ... ... ... ... . . ",
"t X X X 3 < ....- & ..@ @ . ..... ... ....... ",
"t ",
"t ......................................] ( E ",
"t ..................................] ] ( ~ I ",
"t .... ...... ........ ...... ....] K ",
"t .......... .. .... ...... .. ] ( I Z ",
"t .... .... ........ ...... ...... N ",
"t .... .. ...... .... ..( I K ",
"t .... .... ........ ...... ..] ( I Z ",
"t .... .... .......... .... ] ( ~ I z ",
"t ..........................] ] ( ~ E G Z z h ",
"t ........................] ] ~ E K G N z k h ",
"t ..................] ( ~ G N m d d ",
"t ........] ....] .. ( ~ E G Z k y ",
"t ] ..] ..] ] ] ] ( ( E K h h y y ",
"y ( ] ( ( ] ( ( ~ ~ I K N k h d y y y y ",
"y ~ ~ E E E E E I K m z h t t y y ",
"t I K K K K K G G Z N z k d y y t w t t t t y ",
"t Z Z Z Z N N m m m k h d y t t w w w w t y y "
};

206
src/toolbar_objedit.xpm Normal file
View File

@@ -0,0 +1,206 @@
/* XPM */
static const char *toolbar_objedit[] = {
/* columns rows colors chars-per-pixel */
"24 24 176 2",
" c black",
". c #7F7F00000000",
"X c #CDCD00003535",
"o c red",
"O c #8B8B82820000",
"+ c #8C8C82820000",
"@ c #8C8C83830000",
"# c #8D8D83830000",
"$ c #8D8D84840000",
"% c #8E8E85850000",
"& c #8F8F85850000",
"* c #8F8F86860000",
"= c #909086860000",
"- c #909087870000",
"; c #919188880000",
": c #929288880000",
"> c #929289890000",
", c #939389890000",
"< c #93938A8A0000",
"1 c #95958B8B0000",
"2 c #96968C8C0000",
"3 c #97978D8D0000",
"4 c #97978E8E0000",
"5 c #98988E8E0000",
"6 c #9A9A90900000",
"7 c #9B9B91910000",
"8 c #9C9C92920000",
"9 c #9C9C93930000",
"0 c #9D9D93930000",
"q c #9E9E93930000",
"w c #9F9F94940000",
"e c #A0A096960000",
"r c #A0A097970000",
"t c #A2A297970000",
"y c #A2A298980000",
"u c #A3A398980000",
"i c #A2A29B9B0000",
"p c #A4A499990000",
"a c #A4A49A9A0000",
"s c #A6A69B9B0000",
"d c #A6A69C9C0000",
"f c #A7A79D9D0000",
"g c #A8A89E9E0000",
"h c #A9A99E9E0000",
"j c #A9A99F9F0000",
"k c #AAAA9F9F0000",
"l c #A9A9A2A20000",
"z c #AAAAA0A00000",
"x c #ABABA0A00000",
"c c #ABABA1A10000",
"v c #A9A9A4A40000",
"b c #ACACA1A10000",
"n c #ADADA2A20000",
"m c #AEAEA3A30000",
"M c #ADADA7A70000",
"N c #AFAFA4A40000",
"B c #B0B0A5A50000",
"V c #B0B0A6A60000",
"C c #B1B1A6A60000",
"Z c #B1B1A7A70000",
"A c #B2B2A7A70000",
"S c #B2B2A8A80000",
"D c #B3B3A8A80000",
"F c #B2B2ACAC0000",
"G c #B4B4A9A90000",
"H c #B5B5ACAC0000",
"J c #B4B4AEAE0000",
"K c #B5B5AFAF0000",
"L c #B7B7ACAC0000",
"P c #B7B7ADAD0000",
"I c #B8B8ADAD0000",
"U c #B8B8AEAE0000",
"Y c #B9B9AFAF0000",
"T c #B8B8B4B40000",
"R c #BABAB5B50000",
"E c #BBBBB6B60000",
"W c #BCBCB2B20000",
"Q c #BCBCB3B30000",
"! c #BCBCB7B70000",
"~ c #BEBEB4B40000",
"^ c #BFBFB5B50000",
"/ c #BDBDB8B80000",
"( c #C0C0B6B60000",
") c #C0C0BABA0000",
"_ c #C2C2B8B80000",
"` c #C3C3B9B90000",
"' c #C0C0BCBC0000",
"] c #C2C2BDBD0000",
"[ c #C3C3BEBE0000",
"{ c #C4C4BABA0000",
"} c #C4C4BBBB0000",
"| c #C5C5BCBC0000",
" . c #C7C7BFBF0000",
".. c #C5C5C1C10000",
"X. c #C7C7C3C30000",
"o. c #C9C9C0C00000",
"O. c #C9C9C1C10000",
"+. c #C8C8C3C30000",
"@. c #CACAC1C10000",
"#. c #CBCBC3C30000",
"$. c #C8C8C4C40000",
"%. c #C9C9C5C50000",
"&. c #CBCBC6C60000",
"*. c #CBCBC7C70000",
"=. c #CCCCC4C40000",
"-. c #CECEC6C60000",
";. c #CCCCC8C80000",
":. c #CFCFCBCB0000",
">. c #D0D0C8C80000",
",. c #D1D1C9C90000",
"<. c #D2D2CACA0000",
"1. c #D2D2CBCB0000",
"2. c #D0D0CCCC0000",
"3. c #D1D1CDCD0000",
"4. c #D1D1CECE0000",
"5. c #D2D2CFCF0000",
"6. c #D3D3CFCF0000",
"7. c #D4D4CDCD0000",
"8. c #D3D3D0D00000",
"9. c #D7D7D1D10000",
"0. c #D6D6D2D20000",
"q. c #D7D7D3D30000",
"w. c #D7D7D4D40000",
"e. c #D8D8D2D20000",
"r. c #DADAD4D40000",
"t. c #DCDCD6D60000",
"y. c #DADAD8D80000",
"u. c #DCDCD9D90000",
"i. c #DCDCDADA0000",
"p. c #DDDDDADA0000",
"a. c #DFDFD9D90000",
"s. c #DEDEDBDB0000",
"d. c #DFDFDADA0000",
"f. c #DFDFDCDC0000",
"g. c #DFDFDDDD0000",
"h. c #E0E0DBDB0000",
"j. c #E1E1DCDC0000",
"k. c #E1E1DFDF0000",
"l. c #E3E3DEDE0000",
"z. c #E3E3E1E10000",
"x. c #E3E3E2E20000",
"c. c #E6E6E2E20000",
"v. c #E7E7E3E30000",
"b. c #E6E6E4E40000",
"n. c #E6E6E5E50000",
"m. c #E9E9E5E50000",
"M. c #E8E8E6E60000",
"N. c #E9E9E6E60000",
"B. c #EAEAE7E70000",
"V. c #EAEAE8E80000",
"C. c #EBEBE9E90000",
"Z. c #EBEBEBEB0000",
"A. c #ECECE9E90000",
"S. c #EDEDEBEB0000",
"D. c #EDEDECEC0000",
"F. c #EEEEEDED0000",
"G. c #EFEFEDED0000",
"H. c #F0F0EFEF0000",
"J. c #F1F1EFEF0000",
"K. c #F1F1F0F00000",
"L. c #F2F2F0F00000",
"P. c #F3F3F1F10000",
"I. c #F4F4F3F30000",
"U. c #F5F5F4F40000",
"Y. c #F6F6F4F40000",
"T. c #F6F6F5F50000",
"R. c #F7F7F5F50000",
"E. c #F8F8F8F80000",
"W. c #F9F9F8F80000",
"Q. c #FAFAF9F90000",
"!. c #FBFBFAFA0000",
"~. c #FCFCFCFC0000",
"^. c #FDFDFCFC0000",
"/. c #FEFEFEFE0000",
"(. c yellow",
"). c None",
/* pixels */
").).).).).).).).).).).).).).).).).).).).).).).).",
").).).).).).).).).).).).).).).).).).).).).).).).",
").).).). ).).).).",
").).). E.U.I.K.K.H. . . Z.C.n.s.q.:. ).).).",
").). U.K.Z.C.N.N. . . C.x.u.8.%.] ).).",
").). H.C.b.z.s.u. . . g.y.8.X.! P ).).",
").). (. z.u.q.8.4. . . w.4.%.! F ~ ).).",
").). (. u.8.;..... . . :.%.] J z Y ).).",
").). (. 0.;.] ! E . . %.] E N w S ).).",
").). (.(. ..~ P v F z ).).",
").). !.E.U. o o o o o o B n d ).).",
").). R.R.I.H.m. o X X X X X Y B g s 0 ).).",
").). U.J.S.m.l. B g s 7 2 ).).",
").). H.A.v.h.r.7.-. . . G N g s 7 5 > ).).",
").). A.v.h.7.:.#.| . . n g e 7 2 > * ).).",
").). x.j.7.:.#.{ ~ Y z s e 7 2 > $ $ ).).",
").). g.7.<. .` ~ P S n z s e 5 < < # # # ).).",
").). h.7.=.{ W P B z g y 7 5 < * * # # O ).).",
").). 7.-.{ W L B z d e 7 2 < * * # # # O ).).",
").).). .( Y A n s e 7 2 > * $ # # O O ).).).",
").).).). ).).).).",
").).).).).).).).).).).).).).).).).).).).).).).).",
").).).).).).).).).).).).).).).).).).).).).).).).",
").).).).).).).).).).).).).).).).).).).).).).).)."
};

210
src/toolbar_open.xpm Normal file
View File

@@ -0,0 +1,210 @@
/* XPM */
static const char *toolbar_open[] = {
/* columns rows colors chars-per-pixel */
"24 24 180 2",
" c black",
". c #76766F6F0000",
"X c #777770700000",
"o c #787871710000",
"O c #797971710000",
"+ c #797972720000",
"@ c #7B7B74740000",
"# c #7C7C74740000",
"$ c #7D7D75750000",
"% c #7E7E76760000",
"& c #7F7F77770000",
"* c #808078780000",
"= c #818179790000",
"- c #82827A7A0000",
"; c #83837B7B0000",
": c #86867E7E0000",
"> c #87877F7F0000",
", c #888880800000",
"< c #8A8A81810000",
"1 c #8A8A82820000",
"2 c #8D8D84840000",
"3 c #8E8E85850000",
"4 c #8E8E86860000",
"5 c #8F8F86860000",
"6 c #919188880000",
"7 c #93938A8A0000",
"8 c #94948B8B0000",
"9 c #95958B8B0000",
"0 c #95958C8C0000",
"q c #95958D8D0000",
"w c #98988E8E0000",
"e c #9A9A90900000",
"r c #9A9A91910000",
"t c #9C9C93930000",
"y c #9E9E93930000",
"u c #9C9C94940000",
"i c #A0A096960000",
"p c #A0A097970000",
"a c #A1A197970000",
"s c #A1A198980000",
"d c #A2A298980000",
"f c #A3A39B9B0000",
"g c #A6A69B9B0000",
"h c #A5A59C9C0000",
"j c #A7A79E9E0000",
"k c #A8A89F9F0000",
"l c #A9A99F9F0000",
"z c #AAAAA0A00000",
"x c #AAAAA1A10000",
"c c #ABABA1A10000",
"v c #AAAAA2A20000",
"b c #ADADA4A40000",
"n c #AFAFA4A40000",
"m c #AFAFA5A50000",
"M c #AEAEA6A60000",
"N c #B0B0A8A80000",
"B c #B2B2A9A90000",
"V c #B3B3A8A80000",
"C c #B2B2AAAA0000",
"Z c #B3B3AAAA0000",
"A c #B4B4ADAD0000",
"S c #B6B6ACAC0000",
"D c #B7B7AFAF0000",
"F c #B8B8ACAC0000",
"G c #B8B8ADAD0000",
"H c #B9B9ADAD0000",
"J c #B8B8AEAE0000",
"K c #B9B9AFAF0000",
"L c #BABAAEAE0000",
"P c #BABAAFAF0000",
"I c #BBBBAFAF0000",
"U c #BBBBB0B00000",
"Y c #BABAB2B20000",
"T c #BBBBB3B30000",
"R c #BCBCB0B00000",
"E c #BCBCB1B10000",
"W c #BCBCB3B30000",
"Q c #BDBDB2B20000",
"! c #BEBEB3B30000",
"~ c #BCBCB4B40000",
"^ c #BEBEB4B40000",
"/ c #BFBFB5B50000",
"( c #BEBEB7B70000",
") c #BFBFB7B70000",
"_ c #C0C0B5B50000",
"` c #C1C1B6B60000",
"' c #C0C0B8B80000",
"] c #C1C1B8B80000",
"[ c #C1C1B9B90000",
"{ c #C2C2B8B80000",
"} c #C3C3B9B90000",
"| c #C3C3BABA0000",
" . c #C4C4BABA0000",
".. c #C5C5BBBB0000",
"X. c #C4C4BCBC0000",
"o. c #C5C5BCBC0000",
"O. c #C4C4BEBE0000",
"+. c #C6C6BCBC0000",
"@. c #C6C6BDBD0000",
"#. c #C6C6BFBF0000",
"$. c #C7C7BEBE0000",
"%. c #C7C7BFBF0000",
"&. c #C8C8BFBF0000",
"*. c #C6C6C0C00000",
"=. c #C9C9C0C00000",
"-. c #C8C8C2C20000",
";. c #CACAC1C10000",
":. c #CBCBC2C20000",
">. c #CBCBC4C40000",
",. c #CCCCC5C50000",
"<. c #CDCDC6C60000",
"1. c #CDCDC7C70000",
"2. c #CECEC5C50000",
"3. c #CECEC6C60000",
"4. c #CECEC7C70000",
"5. c #CFCFC7C70000",
"6. c #CECEC8C80000",
"7. c #CECEC9C90000",
"8. c #D0D0C8C80000",
"9. c #D0D0C9C90000",
"0. c #D2D2CBCB0000",
"q. c #D3D3CBCB0000",
"w. c #D2D2CDCD0000",
"e. c #D4D4CDCD0000",
"r. c #D4D4CECE0000",
"t. c #D5D5CECE0000",
"y. c #D5D5CFCF0000",
"u. c #D6D6CFCF0000",
"i. c #D5D5D0D00000",
"p. c #D6D6D0D00000",
"a. c #D6D6D1D10000",
"s. c #D8D8D1D10000",
"d. c #D8D8D2D20000",
"f. c #DADAD5D50000",
"g. c #DBDBD5D50000",
"h. c #DBDBD6D60000",
"j. c #DCDCD6D60000",
"k. c #DDDDD7D70000",
"l. c #DDDDD8D80000",
"z. c #DDDDD9D90000",
"x. c #DEDED8D80000",
"c. c #DEDEDADA0000",
"v. c #E0E0DADA0000",
"b. c #E0E0DCDC0000",
"n. c #E1E1DCDC0000",
"m. c #E1E1DDDD0000",
"M. c #E2E2DDDD0000",
"N. c #E2E2DEDE0000",
"B. c #E3E3DFDF0000",
"V. c #E4E4DFDF0000",
"C. c #E4E4E0E00000",
"Z. c #E5E5E1E10000",
"A. c #E5E5E2E20000",
"S. c #E6E6E2E20000",
"D. c #E6E6E3E30000",
"F. c #E7E7E4E40000",
"G. c #E9E9E5E50000",
"H. c #EAEAE7E70000",
"J. c #EBEBE8E80000",
"K. c #ECECE8E80000",
"L. c #ECECE9E90000",
"P. c #EDEDEAEA0000",
"I. c #EDEDEBEB0000",
"U. c #EFEFEBEB0000",
"Y. c #EFEFEDED0000",
"T. c #F0F0EEEE0000",
"R. c #F1F1EEEE0000",
"E. c #F1F1EFEF0000",
"W. c #F2F2EFEF0000",
"Q. c #F3F3F0F00000",
"!. c #F3F3F1F10000",
"~. c #F4F4F2F20000",
"^. c #F4F4F3F30000",
"/. c #F5F5F4F40000",
"(. c #F7F7F5F50000",
"). c #F7F7F6F60000",
"_. c #F9F9F8F80000",
"`. c #FAFAF9F90000",
"'. c #FBFBFBFB0000",
"]. c None",
/* pixels */
"].].].].].].].].].].].].].].].].].].].].].].].].",
"].].].].].].].].].].].].].].].].].].].].].].].].",
"].].].].].].].].].].].].].].].].].].].].].].].].",
"].].].]. ].].].].].].].].].].].].].].",
"].].]. !.T.U.H.C.M. ].].].].].].].].].].].].].",
"].]. T.L.H.C.c.g.d.e. ].].].].].",
"]. T.L.C.M.g.u.q.2.:.&.+.{ ` ! ! Y ! ].].].].",
"]. H.C.c.d.q.2.:.+. .{ ` ! ! I F F F ].].].].",
"]. B.c.u.7.:.:. .` ` ! ! ! F F F F F ].].].].",
"]. g.e.7. ].].].",
"]. e.5.:. '._._.)./.!.I.D.c.u.:.{ F Z b ].].",
"]. 2.:. _././.!.T.I.H.C.f.q.:.{ F m x h ].].",
"]. :. . /.T.T.L.D.M.c.u.1.*.T Z c h s y ].].",
"]. +.{ I.L.C.M.h.u.7.*.( A b h i r w q ].].",
"]. . L.C.M.f.r.7.*.( D M j u r 7 5 4 ].].].",
"]. { C.c.u.7.*.( D C j s r q 4 < < : ].].].",
"]. { c.e.2.| Y C x s u q 5 < : ; - % ].].].",
"]. c.e.2.{ Y C x i r 7 4 > - * % % ].].].].",
"]. f.7.+.~ C x s r 7 2 > - % @ @ . ].].].].",
"]. d.7.{ F b h u q 4 > ; * # @ . . ].].].].",
"].]. ].].].].].",
"].].].].].].].].].].].].].].].].].].].].].].].].",
"].].].].].].].].].].].].].].].].].].].].].].].].",
"].].].].].].].].].].].].].].].].].].].].].].].]."
};

202
src/toolbar_picedit.xpm Normal file
View File

@@ -0,0 +1,202 @@
/* XPM */
static const char *toolbar_picedit[] = {
/* columns rows colors chars-per-pixel */
"24 24 172 2",
" c black",
". c #000065650000",
"X c #000066660000",
"o c #000067670000",
"O c #000068680000",
"+ c #000069690000",
"@ c #00006A6A0000",
"# c #00006B6B0000",
"$ c #00006C6C0000",
"% c #00006D6D0000",
"& c #00006E6E0000",
"* c #00006F6F0000",
"= c #000070700000",
"- c #000071710000",
"; c #5A5A00000000",
": c #5B5B00000000",
"> c #5C5C00000000",
", c #5D5D00000000",
"< c #5E5E00000000",
"1 c #5F5F00000000",
"2 c #616100000000",
"3 c #626200000000",
"4 c #646400000000",
"5 c #00000000ACAC",
"6 c #00000000ADAD",
"7 c #00000000AEAE",
"8 c #00000000AFAF",
"9 c #00000000B1B1",
"0 c #00000000B2B2",
"q c #00000000B4B4",
"w c #00000000B5B5",
"e c #00000000B7B7",
"r c #00000000B8B8",
"t c #00000000BABA",
"y c #00000000BCBC",
"u c #00000000BEBE",
"i c #00000000BFBF",
"p c #00000000C1C1",
"a c #00000000C2C2",
"s c #00000000C3C3",
"d c #00000000C4C4",
"f c #00000000C6C6",
"g c #00000000C7C7",
"h c #00000000C8C8",
"j c #00000000CACA",
"k c #00000000CBCB",
"l c #00000000CCCC",
"z c #00000000CECE",
"x c #00000000D0D0",
"c c #00000000D2D2",
"v c #00000000D4D4",
"b c #00000000D5D5",
"n c #00000000D6D6",
"m c #00000000D8D8",
"M c #00000000DADA",
"N c #00000000DBDB",
"B c #00000000DCDC",
"V c #00000000DEDE",
"C c #00000000E0E0",
"Z c #00000000E1E1",
"A c #00000000E2E2",
"S c #00000000E3E3",
"D c #00000000E5E5",
"F c #00000000E7E7",
"G c #00000000E9E9",
"H c #00000000EAEA",
"J c #00000000EBEB",
"K c #00000000ECEC",
"L c #00000000EDED",
"P c #00000000EFEF",
"I c #0000ACAC0000",
"U c #0000ADAD0000",
"Y c #0000AFAF0000",
"T c #0000B0B00000",
"R c #0000B1B10000",
"E c #0000B2B20000",
"W c #0000B3B30000",
"Q c #0000B4B40000",
"! c #0000B5B50000",
"~ c #0000B6B60000",
"^ c #0000B7B70000",
"/ c #0000B9B90000",
"( c #0000BBBB0000",
") c #0000BCBC0000",
"_ c #0000BEBE0000",
"` c #0000BFBF0000",
"' c #0000C1C10000",
"] c #0000C2C20000",
"[ c #0000C3C30000",
"{ c #0000C5C50000",
"} c #0000C7C70000",
"| c #0000C8C80000",
" . c #0000C9C90000",
".. c #0000CACA0000",
"X. c #0000CBCB0000",
"o. c #0000CCCC0000",
"O. c #0000CDCD0000",
"+. c #0000CECE0000",
"@. c #0000CFCF0000",
"#. c #0000D0D00000",
"$. c #0000D1D10000",
"%. c #0000D2D20000",
"&. c #0000D3D30000",
"*. c #0000D5D50000",
"=. c #0000D6D60000",
"-. c #0000D7D70000",
";. c #0000D8D80000",
":. c #0000D9D90000",
">. c #0000DADA0000",
",. c #0000DBDB0000",
"<. c #0000DCDC0000",
"1. c #0000DDDD0000",
"2. c #0000DEDE0000",
"3. c #0000DFDF0000",
"4. c #0000E0E00000",
"5. c #0000E1E10000",
"6. c #0000E2E20000",
"7. c #0000E3E30000",
"8. c #0000E4E40000",
"9. c #0000E5E50000",
"0. c #0000E6E60000",
"q. c #0000E7E70000",
"w. c #0000E8E80000",
"e. c #0000E9E90000",
"r. c #0000EAEA0000",
"t. c #0000EBEB0000",
"y. c #0000ECEC0000",
"u. c #0000EDED0000",
"i. c #0000EEEE0000",
"p. c #0000F0F00000",
"a. c #0000F2F20000",
"s. c #0000F4F40000",
"d. c #0000D2D2D2D2",
"f. c #0000D4D4D4D4",
"g. c #0000D7D7D7D7",
"h. c #0000DADADADA",
"j. c #0000DCDCDCDC",
"k. c #0000DDDDDDDD",
"l. c #0000DFDFDFDF",
"z. c #0000E0E0E0E0",
"x. c #0000E1E1E1E1",
"c. c #0000E2E2E2E2",
"v. c #0000E3E3E3E3",
"b. c #0000E4E4E4E4",
"n. c #0000E5E5E5E5",
"m. c #0000E6E6E6E6",
"M. c #0000E7E7E7E7",
"N. c #0000E8E8E8E8",
"B. c #0000E9E9E9E9",
"V. c #0000EAEAEAEA",
"C. c #0000EBEBEBEB",
"Z. c #0000ECECECEC",
"A. c #0000EDEDEDED",
"S. c #0000EEEEEEEE",
"D. c #0000EFEFEFEF",
"F. c #0000F0F0F0F0",
"G. c #0000F1F1F1F1",
"H. c #0000F2F2F2F2",
"J. c #0000F3F3F3F3",
"K. c #0000F4F4F4F4",
"L. c #0000F5F5F5F5",
"P. c #0000F7F7F7F7",
"I. c #0000F8F8F8F8",
"U. c #F5F5F5F50000",
"Y. c #F6F6F6F60000",
"T. c #F7F7F7F70000",
"R. c #F8F8F8F80000",
"E. c #F9F9F9F90000",
"W. c #FAFAFAFA0000",
"Q. c #FBFBFBFB0000",
"!. c #FCFCFCFC0000",
"~. c gray75",
/* pixels */
"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.",
"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.",
"~. ~.",
"~. !.Q.Q.Q.Q.I.I.K.K.K.G.G.S.Z.V.V.V.n.n.z. ~.",
"~. Q.T.Q.T.Q.I.K.K.G.G.S.S.V.V.V.n.n.- - $ ~.",
"~. Q.Q.T.T.T.K.K.G.D.S.S.V.V.V.n.n.$ - $ $ ~.",
"~. Q.Q.T.T.J.G.G.G.S.S.V.M.n.v.z.- $ $ $ $ ~.",
"~. T.T.T.K.G.G.S.S.Z.S.n.n.n.z.- $ $ # # # ~.",
"~. I.K.K.G.G.D.S.V.V.n.n.z.z.l.h.# # # X X ~.",
"~. K.K.G.D.S.S.V.V.n.n.z.z.l.h.g.d.d.X X X ~.",
"~. s.p.p.y.y.y.0.0.5.5.2.2.;.-.&.&.O.X.4 3 ~.",
"~. s.p.y.y.q.0.0.5.5.2.;.;.-.&.&.O.X.} 3 3 ~.",
"~. p.p.y.q.q.0.5.2.2.;.;.-.&.O.O.X.} } 3 , ~.",
"~. P L q.q.q.0.5.2.;.-.-.&.O.X.} } [ ( , , ~.",
"~. L J D 0.5.2.2.;.-.-.O.O.O.} } [ ( , , , ~.",
"~. J J D S 5.2.;.-.-.&.O.X.} } [ [ , , : : ~.",
"~. J D S N N N v v c O.X.X.} [ ( ( / ~ ~ R ~.",
"~. q.S S N N M v c l l g g p i ( / / ~ R Y ~.",
"~. 0.5.2.N M v c c l h g p i i t t 0 0 0 5 ~.",
"~. 0.5.2.;.-.-.&.O.h g p p i t t 0 0 0 5 5 ~.",
"~. 5.5.;.;.-.&.&.X.} } [ ( ( / ~ R R R Y Y ~.",
"~. ~.",
"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.",
"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~."
};

130
src/toolbar_run.xpm Normal file
View File

@@ -0,0 +1,130 @@
/* XPM */
static const char *toolbar_run[] = {
/* columns rows colors chars-per-pixel */
"24 24 100 2",
" c black",
". c gray50",
"X c #939300002525",
"o c #929200002626",
"O c #949401012525",
"+ c #959502022626",
"@ c #969601012525",
"# c #979702022626",
"$ c #989803032626",
"% c #9A9A02022525",
"& c #9D9D02022323",
"* c #9C9C05052626",
"= c #AAAA02021F1F",
"- c #AFAF03031F1F",
"; c #B3B304041F1F",
": c #B8B807071F1F",
"> c #A0A000002121",
", c #A2A205052525",
"< c #A4A400002020",
"1 c #A5A501012020",
"2 c #A4A404042323",
"3 c #A8A806062424",
"4 c #AEAE07072222",
"5 c #ABAB09092727",
"6 c #B1B105052020",
"7 c #B4B40C0C2525",
"8 c #BFBF0B0B2020",
"9 c #BCBC0D0D2424",
"0 c #BFBF15152A2A",
"q c #C6C60C0C1F1F",
"w c #C7C70F0F2323",
"e c #C3C312122727",
"r c #C6C618182B2B",
"t c #CDCD16162727",
"y c #CBCB1B1B2D2D",
"u c #CBCB1C1C2E2E",
"i c #CDCD1B1B2C2C",
"p c #D0D011112121",
"a c #D7D715152222",
"s c #D4D415152424",
"d c #D7D719192727",
"f c #D3D31D1D2C2C",
"g c #D5D51A1A2929",
"h c #DCDC18182424",
"j c #DBDB1E1E2B2B",
"k c #D6D622222F2F",
"l c #DDDD20202C2C",
"z c #DDDD21212D2D",
"x c #D9D926263232",
"c c #DADA24243131",
"v c #E3E320202929",
"b c #E3E322222B2B",
"n c #E3E326262F2F",
"m c #E6E620202828",
"M c #E6E623232D2D",
"N c #E5E525252D2D",
"B c #EAEA23232A2A",
"V c #EAEA25252C2C",
"C c #EDED28282D2D",
"Z c #ECEC28282E2E",
"A c #E1E128283131",
"S c #E4E42D2D3636",
"D c #E6E62C2C3434",
"F c #E6E62F2F3737",
"G c #E8E828283030",
"H c #E9E92B2B3232",
"J c #EBEB2D2D3333",
"K c #EAEA2D2D3434",
"L c #EFEF2B2B3131",
"P c #EEEE2F2F3434",
"I c #EFEF32323737",
"U c #ECEC33333939",
"Y c #EFEF37373C3C",
"T c #EFEF38383D3D",
"R c #F3F32F2F3232",
"E c #F1F130303434",
"W c #F2F232323636",
"Q c #F6F634343737",
"! c #F3F335353939",
"~ c #F3F337373B3B",
"^ c #F6F638383A3A",
"/ c #F4F43A3A3D3D",
"( c #F6F63C3C3E3E",
") c #F9F93C3C3E3E",
"_ c #F7F73E3E4040",
"` c #F8F83F3F4040",
"' c #FAFA3F3F4040",
"] c #F8F840404141",
"[ c #FAFA40404141",
"{ c #FBFB42424343",
"} c #F9F942424444",
"| c #FAFA45454646",
" . c #FBFB45454646",
".. c #FBFB47474747",
"X. c #FBFB48484848",
"o. c #FBFB49494A4A",
"O. c #FCFC49494A4A",
"+. c #FCFC4B4B4C4C",
"@. c #FDFD4D4D4E4E",
"#. c None",
/* pixels */
"#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.",
"#.#.#.#.#.#.#.#.#.#.#.#.#. #.#.#.#.#.#.#.#.",
"#.#.#.#.#.. . . . . #.#. O.[ Q #.#.#.#.#.#.#.",
"#.#.#.#.#.#.#.#.#.#.#. @.X.` W V #.#.#.#.#.#.",
"#.#.#.#.#.#.#.#.#.#.#. +.| ( P b #.#.#.#.#.#.",
"#.#.#.#.#.. . . . . #. X.} ~ H j #.#.#.#.#.#.",
"#.#.#.#.#.#.#.#.#.#.#. ..` U n g #.#.#.#.#.#.",
"#.#.#.#.#.#.#.#.#.#.#.#. / J l #.#.#.#.#.#.#.",
"#.#.#.#.. . . . . #.#. [ W H #.#.#.#.#.#.#.#.",
"#.#.#.#.#.#.#.#.#.#. ..) W M #.#.#.#.#.#.#.#.",
"#.#.#.#.#.#.#.#.#.#. { ^ L v s #.#.#.#.",
"#.#.#.#.. . . . . #. ' Q C t ; = = #.#.#.",
"#.#.#.#.#.#.#.#.#.#.#. R B h 4 = & #.#.#.",
"#.#.#.#.#.#.#.#.#.#.#.#. m a q 8 #.#.#.#.",
"#.#.#.#.#.. . . . . #. V q 6 #.#.#.#.#.#.",
"#.#.#.#.#.#.#.#.#.#.#. n d w #.#.#.#.#.#.#.",
"#.#.#.#.#.#.#.#.#.#. D l t 9 4 2 #.#.#.#.#.#.",
"#.#.. . . . . #.#. U A f e 7 3 & #.#.#.#.#.#.",
"#.#.#.#.#.#.#.#. T S k y 5 , $ X #.#.#.#.#.",
"#.#.#.#.#.#.#. T F x i #. * $ X #.#.#.#.#.",
"#.. . . . . #. D c i #.#. $ X o X #.#.#.#.",
"#.#.#.#.#.#.#.#. i 0 #.#.#. X X o X #.#.#.",
"#.#.#.#.#.#.#.#.#. #.#.#.#.#. #.#.#.",
"#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#."
};

116
src/toolbar_textedit.xpm Normal file
View File

@@ -0,0 +1,116 @@
/* XPM */
static const char *toolbar_textedit[] = {
/* columns rows colors chars-per-pixel */
"24 24 86 1",
" c black",
". c #000000007F7F",
"X c #7F7F00007F7F",
"o c #7F7F7F7F0000",
"O c navy",
"+ c #000000008181",
"@ c #000000008282",
"# c #000000008383",
"$ c #000000008686",
"% c #000000008787",
"& c #000000008888",
"* c #000000008B8B",
"= c #000000008C8C",
"- c #000000009393",
"; c #000000009595",
": c #000000009898",
"> c #000000009D9D",
", c #000000009E9E",
"< c #00000000A6A6",
"1 c #00000000A9A9",
"2 c #00000000AAAA",
"3 c #00000000ACAC",
"4 c #00000000B3B3",
"5 c #00000000B9B9",
"6 c #00000000BFBF",
"7 c #00000000C1C1",
"8 c #00000000C3C3",
"9 c #00000000C6C6",
"0 c #00000000C8C8",
"q c #00000000CBCB",
"w c #00000000CCCC",
"e c MediumBlue",
"r c #00000000CECE",
"t c red",
"y c yellow",
"u c gray75",
"i c gray80",
"p c #CDCDCDCDCDCD",
"a c #CECECECECECE",
"s c gray81",
"d c #D0D0D0D0D0D0",
"f c gray82",
"g c #D2D2D2D2D2D2",
"h c LightGray",
"j c gray83",
"k c #D5D5D5D5D5D5",
"l c gray84",
"z c #D7D7D7D7D7D7",
"x c #D8D8D8D8D8D8",
"c c gray85",
"v c #DADADADADADA",
"b c gray86",
"n c gainsboro",
"m c gray87",
"M c #DFDFDFDFDFDF",
"N c #E1E1E1E1E1E1",
"B c #E2E2E2E2E2E2",
"V c gray89",
"C c #E4E4E4E4E4E4",
"Z c gray90",
"A c #E6E6E6E6E6E6",
"S c #E7E7E7E7E7E7",
"D c gray91",
"F c #E9E9E9E9E9E9",
"G c #EAEAEAEAEAEA",
"H c gray92",
"J c #ECECECECECEC",
"K c gray93",
"L c #EEEEEEEEEEEE",
"P c #EFEFEFEFEFEF",
"I c gray94",
"U c #F1F1F1F1F1F1",
"Y c gray95",
"T c #F3F3F3F3F3F3",
"R c #F4F4F4F4F4F4",
"E c gray96",
"W c #F6F6F6F6F6F6",
"Q c gray97",
"! c #F8F8F8F8F8F8",
"~ c #F9F9F9F9F9F9",
"^ c gray98",
"/ c #FBFBFBFBFBFB",
"( c gray99",
") c #FDFDFDFDFDFD",
"_ c #FEFEFEFEFEFE",
"` c gray100",
/* pixels */
"uuuuuuuuuuuuuuuuuuuuuuuu",
"u ",
"u yoyw```0```2`:`*```+``",
"u oytww`09``2,;`*$+`++``",
"u yot09`65`<,-`$`++`..`.",
"u XXX76`43```*`+`..`..``",
"u ",
"u ``````````````````````",
"u ``````````````````````",
"u ``````` ``````````` ``",
"u `` ``` ``````````` `^",
"u ```` `` ``` `` ^^",
"u `` `` `` ` ``` `` ^U",
"u ` `` `` `` ` ``` `^ WL",
"u `` `` ``` `` LZ",
"u ```````````````^WWULZm",
"u ```````` ``^^^WUULGVmz",
"u `` ``` ` ^UW LG Vbzh",
"u ` `` ^^ WWUL G Vm bzpp",
"u ` W LGZV bz pp",
"u ^ WWUUL ZVmmbz hh pp p",
"u WW ZV mbzh ppp pp p",
"u ULGZVmbzzhhpppppppiipi",
"u GZVmbzzhhhpppppppiiiii"
};

64
src/toolbar_viewedit.xpm Normal file
View File

@@ -0,0 +1,64 @@
/* XPM */
static const char *toolbar_viewedit[] = {
/* columns rows colors chars-per-pixel */
"24 24 34 1",
" c black",
". c #7F7F00000000",
"X c gray30",
"o c cyan",
"O c #808000000000",
"+ c #CFCF00003333",
"@ c #CDCD00003434",
"# c #CDCD00003535",
"$ c #CECE00003434",
"% c #D2D200002F2F",
"& c #D7D700002B2B",
"* c #D5D500002C2C",
"= c #DADA00002727",
"- c #DFDF00002121",
"; c #DFDF00002222",
": c #D0D000003131",
"> c #D0D000003232",
", c #E1E100001F1F",
"< c #E5E500001C1C",
"1 c #EAEA00001616",
"2 c #EDED00001313",
"3 c #EFEF00001010",
"4 c #F3F300000D0D",
"5 c #F7F700000808",
"6 c #FAFA00000505",
"7 c #FBFB00000404",
"8 c #FEFE00000101",
"9 c #F8F800000808",
"0 c #F0F000001010",
"q c #FFFF50505050",
"w c #FFFFAEAE0000",
"e c yellow",
"r c gray59",
"t c None",
/* pixels */
"tttttttttttttttttttttttt",
"ttttt..ttttttttttttttttt",
"ttttt....ttttttttttttttt",
"tttttoo..rtttttttttttttt",
"tttttoooooottttttttttttt",
"tttttoooooooottttttttttt",
"tttttXXXXXXeettttttttttt",
"tttttXXXXeeeeeettttttttt",
"tttttXXXXeeeerrttttttttt",
"tttttXXeee tttttttttt",
"ttttttreee www ttttttttt",
"tttttttqqq ww 7 tttttttt",
"tttttqqqqq w 753 ttttttt",
"tttttqqqqqq 8741- tttttt",
"tttttqqeeqqr 53<=% ttttt",
"tttttqqeeqqrt 3,&># tttt",
"tttttqqeeqqrtt -*>## ttt",
"tttttqqeeqqrttt *+## ttt",
"tttttqqeeeertttt >+# ttt",
"tttttqqOOeeeetttt tttt",
"tttttOOOOOOeettttttttttt",
"tttttoooooorrttttttttttt",
"tttttoooooortttttttttttt",
"tttttttttttttttttttttttt"
};

208
src/toolbar_wordsedit.xpm Normal file
View File

@@ -0,0 +1,208 @@
/* XPM */
static const char *toolbar_wordsedit[] = {
/* columns rows colors chars-per-pixel */
"24 24 178 2",
" c black",
". c #00002F2F6E6E",
"X c #00002F2F6F6F",
"o c #00002D2D7070",
"O c #00002C2C7373",
"+ c #00002F2F7171",
"@ c #00002F2F7373",
"# c #00002D2D7676",
"$ c #00002F2F7B7B",
"% c #000030306D6D",
"& c #000032326C6C",
"* c #000033336C6C",
"= c #000033336E6E",
"- c #000033336F6F",
"; c #000034346B6B",
": c #000035356A6A",
"> c #000037376969",
", c #000036366A6A",
"< c #000033337171",
"1 c #000032327676",
"2 c #000035357373",
"3 c #000030307A7A",
"4 c #000035357878",
"5 c #000034347E7E",
"6 c #000034347F7F",
"7 c #000038387676",
"8 c #00003B3B7A7A",
"9 c #00003A3A7C7C",
"0 c #00003F3F7E7E",
"q c #00003F3F7F7F",
"w c #777777777777",
"e c gray47",
"r c #797979797979",
"t c gray48",
"y c #7B7B7B7B7B7B",
"u c #7C7C7C7C7C7C",
"i c gray49",
"p c #7E7E7E7E7E7E",
"a c gray50",
"s c #00003B3B8282",
"d c #00003B3B8484",
"f c #00003C3C8484",
"g c #000042428686",
"h c #000045458383",
"j c #000043438989",
"k c #000044448989",
"l c #00004B4B8A8A",
"z c #00004D4D8888",
"x c #00004E4E8E8E",
"c c #000053538D8D",
"v c #000054548B8B",
"b c #00005B5B8F8F",
"n c #000055559191",
"m c #000058589292",
"M c #000059599292",
"N c #00005B5B9191",
"B c #00005E5E9494",
"V c #000061619292",
"C c #000061619494",
"Z c #000060609797",
"A c #000061619696",
"S c #000066669696",
"D c #000066669797",
"F c #000067679999",
"G c #000069699A9A",
"H c #00006B6B9898",
"J c #00006B6B9A9A",
"K c #00006C6C9B9B",
"L c #00006F6F9A9A",
"P c #00006F6F9B9B",
"I c #00006D6D9C9C",
"U c #000072729B9B",
"Y c #000071719D9D",
"T c #000072729C9C",
"R c #000073739E9E",
"E c #000074749E9E",
"W c #000075759E9E",
"Q c #000076769E9E",
"! c #000076769F9F",
"~ c #000077779E9E",
"^ c #000077779F9F",
"/ c #000078789F9F",
"( c #000079799F9F",
") c #808080808080",
"_ c #818181818181",
"` c gray51",
"' c #838383838383",
"] c #848484848484",
"[ c gray52",
"{ c #868686868686",
"} c gray53",
"| c #888888888888",
" . c #8B8B8B8B8B8B",
".. c gray55",
"X. c #8D8D8D8D8D8D",
"o. c #8E8E8E8E8E8E",
"O. c gray56",
"+. c gray57",
"@. c #939393939393",
"#. c gray58",
"$. c #959595959595",
"%. c gray59",
"&. c #979797979797",
"*. c #989898989898",
"=. c #9B9B9B9B9B9B",
"-. c #9D9D9D9D9D9D",
";. c #9F9F9F9F9F9F",
":. c #A0A0A0A0A0A0",
">. c gray63",
",. c gray64",
"<. c #A4A4A4A4A4A4",
"1. c gray65",
"2. c gray66",
"3. c #A9A9A9A9A9A9",
"4. c #AAAAAAAAAAAA",
"5. c #ACACACACACAC",
"6. c gray68",
"7. c #AEAEAEAEAEAE",
"8. c gray69",
"9. c #B1B1B1B1B1B1",
"0. c #B2B2B2B2B2B2",
"q. c gray70",
"w. c gray71",
"e. c #B6B6B6B6B6B6",
"r. c gray72",
"t. c gray73",
"y. c #BBBBBBBBBBBB",
"u. c #BCBCBCBCBCBC",
"i. c gray74",
"p. c gray75",
"a. c #C0C0C0C0C0C0",
"s. c #C1C1C1C1C1C1",
"d. c gray76",
"f. c #C3C3C3C3C3C3",
"g. c gray77",
"h. c #C5C5C5C5C5C5",
"j. c gray78",
"k. c #C8C8C8C8C8C8",
"l. c gray79",
"z. c #CACACACACACA",
"x. c #CBCBCBCBCBCB",
"c. c gray80",
"v. c #CDCDCDCDCDCD",
"b. c #CECECECECECE",
"n. c gray81",
"m. c #D2D2D2D2D2D2",
"M. c LightGray",
"N. c gray83",
"B. c #D7D7D7D7D7D7",
"V. c #D8D8D8D8D8D8",
"C. c #DADADADADADA",
"Z. c gainsboro",
"A. c #DDDDDDDDDDDD",
"S. c #DFDFDFDFDFDF",
"D. c gray88",
"F. c #E1E1E1E1E1E1",
"G. c #E2E2E2E2E2E2",
"H. c #E4E4E4E4E4E4",
"J. c #E6E6E6E6E6E6",
"K. c #E7E7E7E7E7E7",
"L. c gray91",
"P. c gray92",
"I. c #ECECECECECEC",
"U. c gray93",
"Y. c #EEEEEEEEEEEE",
"T. c #EFEFEFEFEFEF",
"R. c gray94",
"E. c #F1F1F1F1F1F1",
"W. c gray95",
"Q. c #F3F3F3F3F3F3",
"!. c gray96",
"~. c #F6F6F6F6F6F6",
"^. c #F8F8F8F8F8F8",
"/. c #F9F9F9F9F9F9",
"(. c gray98",
"). c #FBFBFBFBFBFB",
"_. c gray99",
"`. c None",
/* pixels */
"`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.",
"`.`.`. `.`.`.",
"`.`. ).(._.(.(.).~.W.W.I.K.F.Z.V.m.b.z.j. `.`.",
"`. )._._.(.(.^.!.W.R.P.K.F.Z.B.m.c.k.g.s.s. `.",
"`. ).).E E E ( ( ( ( ( E E E E P F B n p.t. `.",
"`. ).).(.^.!.W.I.L.G.Z.V.B.n.x.j.s.s.i.t.y. `.",
"`. ).).( ( ( ( ( ( E E T K F A c n j s e.q. `.",
"`. ).).~.W.I.K.F.C.M.n.z.j.f.s.p.i.w.q.8.7. `.",
"`. ^.^.( ( E E T P F D B c x k s 6 $ $ 2.1. `.",
"`. ~.W.Y.K.F.V.B.b.z.s.a.i.y.w.0.5.2.<.;.-. `.",
"`. W.Y.U K H D B N c l g s 6 3 # O . . &.$. `.",
"`. U.K.G.C.m.b.s.i.y.w.0.7.4.<.,.=.&.@.O... `.",
"`. K.Z.V b v z h 0 9 4 1 @ @ . = & : : [ [ `.",
"`. V.N.b.g.y.w.7.4.<.;.-.*.$.+.o. .[ [ ` ` `.",
"`. n.z.h 0 9 7 2 < = = = : : : : > : : i i `.",
"`. s.y.0.4.<.*.$.+... .| [ [ ` ) p i y y w `.",
"`.`. 7.,.-.$.....| [ ` ` i ` i y y y w w `.`.",
"`.`.`. | ` ` `.`.`.",
"`.`.`.`.`.`. ` i i `.`.`.`.`.`.`.`.`.`.`.`.`.",
"`.`.`.`. ` i y `.`.`.`.`.`.`.`.`.`.`.`.`.`.",
"`.`.`. ` i i y `.`.`.`.`.`.`.`.`.`.`.`.`.`.`.",
"`.`.`. `.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.",
"`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.",
"`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`."
};

24
src/uparrow_x.xpm Normal file
View File

@@ -0,0 +1,24 @@
/* XPM */
static const char *uparrow_x[] = {
/* columns rows colors chars-per-pixel */
"16 16 2 1",
" c black",
". c None",
/* pixels */
"....... .......",
"...... ......",
"..... .....",
".... ....",
"... ...",
".. ..",
". .",
" ",
" ",
"...... ......",
"...... ......",
"...... ......",
"...... ......",
"...... ......",
"...... ......",
"................"
};

242
src/util.cpp Normal file
View File

@@ -0,0 +1,242 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include "util.h"
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <cstring>
TStringList::TStringList ()
{
num=0;
max=0;
inc=16;
data=NULL;
}
void TStringList::toLower(void)
{
for(int i=0;i<num;i++){
for(int k=0;k<(int)data[i].length();k++){
data[i][k]=tolower( (int)data[i][k]);
}
}
}
void TStringList::toLower(int i)
{
for(int k=0;k<(int)data[i].length();k++){
data[i][k]=tolower( (int)data[i][k]);
}
}
void TStringList::print(void)
{
for(int i=0;i<num;i++){
printf("%d %s\n",i,data[i].c_str());
}
}
void TStringList::print(int n)
{
printf("num=%d\n",n);
// printf("data[%d]=%p\n",num,data[num]);
printf("%s\n",data[n].c_str());
}
string TStringList::at(int n) const
{
return (string(data[n].c_str()));
}
void TStringList::del(int n)
{
for(int i=n+1;i<num;i++){
data[i-1]=data[i];
}
data[num]="";
num--;
}
void TStringList::replace(int n, const char *str)
{
data[n]=string(str);
}
void TStringList::replace(int n, const string& str)
{
data[n]=string(str);
}
void TStringList::add(const string& str)
{
if(num>=max){
max+=inc;
string *data1 = new string[max];
for(int i=0;i<num;i++){
data1[i]=data[i];
}
delete [] data;
data=data1;
}
// printf("add %d=%s\n",num,str.c_str());
data[num]=string(str);
num++;
}
void TStringList::addsorted(const char *str)
{
addsorted(string(str));
}
void TStringList::addsorted(const string& s)
{
if(num>=max){
max+=inc;
string *data1 = new string[max];
for(int i=0;i<num;i++){
data1[i]=data[i];
}
delete [] data;
data=data1;
}
for(int i=0;i<num;i++){
if(data[i] > s){
for(int k=num;k>i;k--){
data[k]=data[k-1];
}
data[i]=s;
num++;
return;
}
}
data[num++]=s;
}
void TStringList::copy(const TStringList& list)
{
num=list.num;
max=list.max;
delete [] data;
data = new string[max];
for(int i=0;i<num;i++){
data[i]=list.data[i];
}
}
void TStringList::lfree(void)
{
if(max>0){
delete [] data;
data=NULL;
num=0;
max=0;
}
}
//**************************************
string MultStr(const char *str,int NumCopies)
{
char tmp[256];
tmp[0]=0;
for(int i=0;i<NumCopies;i++){
strcat(tmp,str);
}
return string(tmp);
}
string IntToStr(int n)
{
char tmp[256];
sprintf(tmp,"%d",n);
return string(tmp);
}
string IntToStr(byte n)
{
char tmp[256];
sprintf(tmp,"%d",(int)n);
return string(tmp);
}
void toLower(string *str)
{
for(int i=0;i<(int)str->length();i++){
str->at(i)=tolower(str->at(i));
}
}
void toLower(char *str)
{
for(int i=0;i<(int)strlen(str);i++){
str[i]=tolower(str[i]);
}
}
//*********************************

64
src/util.h Normal file
View File

@@ -0,0 +1,64 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef UTIL_H
#define UTIL_H
#include <string>
using namespace std;
#include "global.h"
#define MAX(a,b) ((a>b)?(a):(b))
#define MIN(a,b) ((a<b)?(a):(b))
//*****************************************************
class TStringList
{
public:
TStringList();
void add(const string&);
void addsorted(const char *);
void addsorted(const string&);
void copy(const TStringList&);
void lfree(void);
void print(int);
void print(void);
void toLower(void);
void toLower(int);
void del(int);
void replace(int n, const char *str);
void replace(int n, const string& str);
string at(int) const;
int num;
string *data;
int max;
int inc;
};
//*****************************************************
extern string MultStr(const char *str,int NumCopies);
extern string IntToStr(int n);
extern string IntToStr(byte n);
extern void toLower(string *str);
extern void toLower(char *str);
//*****************************************************
#endif

942
src/view.cpp Normal file
View File

@@ -0,0 +1,942 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
* Part of this code is adapted from Peter Kelly's viewview.pas
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include "game.h"
#include "view.h"
#include "viewedit.h"
#include "menu.h"
#include <stdio.h>
#include <sys/types.h>
#ifndef _WIN32
#include <unistd.h>
#endif
#include <sys/stat.h>
#include <stdlib.h>
#include <ctype.h>
#include <qapplication.h>
static int ResPos,DescPos,ResSize;
//**************************************************
View::View()
{
Description = "";
loops = NULL;
opened = false;
}
//**************************************************
void View::init()
{
ReadViewInfo();
CurLoop = 0;
CurCel = 0;
opened = true;
}
//*************************************************
int View::open(char *filename)
{
FILE *fptr = fopen(filename,"rb");
if(fptr==NULL){
menu->errmes("Can't open file %s ! ",filename);
return 1;
}
struct stat buf;
fstat(fileno(fptr),&buf);
ResourceData.Size=buf.st_size;
fread(ResourceData.Data,ResourceData.Size,1,fptr);
fclose(fptr);
init();
return 0;
}
//**************************************************
int View::open(int ResNum)
{
int err = game->ReadResource(VIEW,ResNum);
if(err)return 1;
init();
return 0;
}
//*************************************************
static byte ReadByte(void)
{
if(ResPos < ResourceData.Size){
return ResourceData.Data[ResPos++];
}
return 0;
}
//**************************************************
static int ReadLSMSWord(void)
{
byte MSbyte,LSbyte;
LSbyte = ReadByte();
MSbyte = ReadByte();
return (LSbyte + MSbyte*256);
}
//**************************************************
static void SeekRes(int seekpos)
{
if (seekpos>=0 && seekpos<=ResourceData.Size-1){
ResPos = seekpos;
}
}
//*************************************************
void View::ReadViewInfo()
{
int CurLoop,CurCel,NumCels,curbyte,i,cel_width,cel_height,cel_transcol;
bool cel_mirror;
NumLoops=0;
CurLoop = 0;
CurCel = 0;
SeekRes(2);
NumLoops = ReadByte();
loops = new Loop[NumLoops];
Description = "";
DescPos = ReadLSMSWord();
if (DescPos > 0){
SeekRes(DescPos);
curbyte=1;
while(curbyte != 0){
curbyte = ReadByte();
if(curbyte !=0){
if(curbyte==0x0a)
Description.append("\\n");
else
Description.append(1,(char)curbyte);
}
}
}
SeekRes(5);
for(CurLoop=0;CurLoop<NumLoops;CurLoop++){
loops[CurLoop] = Loop();
loops[CurLoop].LoopLoc = ReadLSMSWord();
for(i=0;i<CurLoop;i++){
if (loops[CurLoop].LoopLoc == loops[i].LoopLoc){ //if 2 loops point to the same place, then the 2nd is mirrored
loops[CurLoop].mirror = i;
break;
}
}
}
for(i=0;i<NumLoops;i++){
for(int j=0;j<NumLoops;j++){
if(i==j)continue;
if(loops[i].mirror == j){
loops[j].mirror1 = i;
}
}
}
for(CurLoop=0;CurLoop<NumLoops;CurLoop++){
SeekRes(loops[CurLoop].LoopLoc);
NumCels = ReadByte();
loops[CurLoop].numcels(NumCels);
for(CurCel=0;CurCel<NumCels;CurCel++){
loops[CurLoop].CelLoc[CurCel] = ReadLSMSWord();
}
for(CurCel=0;CurCel<NumCels;CurCel++){
SeekRes(loops[CurLoop].LoopLoc+loops[CurLoop].CelLoc[CurCel]);
cel_width = ReadByte();
cel_height = ReadByte();
curbyte = ReadByte();
cel_transcol = (byte)(curbyte & 0x0f);
if( curbyte >= 0x80)
cel_mirror= true;
else
cel_mirror = false;
loops[CurLoop].cel(CurCel,cel_width,cel_height,cel_transcol,cel_mirror);
LoadCel(CurLoop,CurCel);
}
}
}
//*************************************************
void View::LoadCel(int loopno,int celno){
int i0,i1,celX,celY,ChunkLength,ChunkCol,Width, Height,transcol;
byte k,curbyte;
bool mirror;
Width = loops[loopno].cels[celno].width;
Height = loops[loopno].cels[celno].height;
transcol = loops[loopno].cels[celno].transcol;
mirror = loops[loopno].cels[celno].mirror;
SeekRes(loops[loopno].LoopLoc+loops[loopno].CelLoc[celno]+3);
celX = 0;
celY = 0;
while(celY != Height){
curbyte = ReadByte();
if (curbyte > 0){
ChunkCol = (curbyte & 0xF0) / 0x10;
ChunkLength = curbyte & 0x0F;
i0=celX;
i1=i0+ChunkLength*2-1;
for(celX=i0;celX<=i1;celX++){
loops[loopno].cels[celno].data[celY*Width*2+celX] = ChunkCol;
}
}
else{
for(;celX<Width*2;celX++){
loops[loopno].cels[celno].data[celY*Width*2+celX] = transcol;
}
if (mirror && (loops[loopno].mirror!=-1)){
for (celX=0;celX<Width;celX++){
k = loops[loopno].cels[celno].data[celY*Width*2+(Width*2-1-celX)];
loops[loopno].cels[celno].data[celY*Width*2+(Width*2-1-celX)] = loops[loopno].cels[celno].data[celY*Width*2+celX];
loops[loopno].cels[celno].data[celY*Width*2+celX] = k;
}
}
celY++;
celX=0;
}
}
}
//*************************************************
int View::save(char *filename)
{
FILE *fptr = fopen(filename,"wb");
if(fptr==NULL){
menu->errmes("Can't open file %s ! ",filename);
return 1;
}
save();
fwrite(ResourceData.Data,ResourceData.Size,1,fptr);
fclose(fptr);
return 0;
}
//*************************************************
int View::save(int ResNum)
{
save();
return(game->AddResource(VIEW,ResNum));
}
//*************************************************
void WriteByte(byte b)
{
if(ResPos >= MaxResourceSize){
menu->errmes("Resource too big !");
return;
}
ResourceData.Data[ResPos++]=b;
if(ResPos > ResSize)ResSize=ResPos;
}
//*************************************************
void View::save()
{
byte c;
int i,j,x,y,length,mirror,k,k1;
int NumCels,CelSize,CelMirrorSize,DescLoc;
bool ColDiff;
short LoopLoc[MaxLoops];
short CelLoc[MaxLoops][MaxCels];
ResSize = 0;
ResPos = 0;
WriteByte(1); //what do these two bytes do?
WriteByte(1);
WriteByte((byte)NumLoops);
WriteByte(0); //write description later, if it exists
WriteByte(0);
LoopLoc[0] = 5 + NumLoops*2;
//fix mirroring so (according to the AGI specs) the loops>=8 do not use it,
//and the mirroring loop number is always higher than the mirrored loop
for (i = 0;i<NumLoops;i++){
k=loops[i].mirror;
k1=loops[i].mirror1;
if(i>=8){
if(k!=-1)unsetMirror(k);
if(k1!=-1)unsetMirror(k1);
}
else if(k!=-1){
if(k>i){
unsetMirror(i);
setMirror(k,i);
}
}
}
for (i = 0;i<NumLoops;i++){
ResPos = LoopLoc[i];
if(loops[i].mirror == -1){
NumCels =loops[i].NumCels;
WriteByte((byte)NumCels);
mirror = loops[i].mirror1;
CelLoc[i][0] = 1 + NumCels*2;
for(int j=0;j<NumCels;j++){
ResPos = LoopLoc[i] + CelLoc[i][j];
int width = loops[i].cels[j].width;
int height = loops[i].cels[j].height;
byte transcol = loops[i].cels[j].transcol;
WriteByte(width);
WriteByte(height);
if(mirror==-1)WriteByte(transcol);
else{
WriteByte(((((byte)i)|0x8)<<4)|(byte)loops[i].cels[j].transcol);
}
CelSize=3;
CelMirrorSize = 3;
for(y=0;y<height;y++){
x=0;
do{
c=loops[i].cels[j].data[y*width*2+x*2];
length=0;
do{
length++;
ColDiff = (loops[i].cels[j].data[y*width*2+(x+length)*2] != c);
}while(!(ColDiff || length>=15 || x+length>=width));
if(x>0 || (x==0 && c!=transcol))CelMirrorSize++;
x+=length;
if(x<width || (x>=width && c!=transcol)){
WriteByte((c<<4)|length);
CelSize++;
}
}while(x<width);
WriteByte(0); //end of line
}
if(mirror!=-1){ //write extra few bytes so mirrored cel will fit
if(CelSize != CelMirrorSize){
for(int t=1;t<=abs(CelSize-CelMirrorSize);t++)WriteByte(0);
}
}
if(j<NumCels-1){
CelLoc[i][j+1]=ResSize-LoopLoc[i];
}
}
}
if(i<NumLoops-1){
LoopLoc[i+1]=ResSize;
}
}
for(i=0;i<NumLoops;i++){
if(loops[i].mirror!=-1){
LoopLoc[i]=LoopLoc[loops[i].mirror];
}
}
ResPos=ResSize;
DescLoc=ResPos;
//write description
if(Description != ""){
for(i=0;i<(int)Description.length();i++){
if(Description[i]=='\\' && (i<(int)Description.length()-1 && Description[i+1]=='n')){
WriteByte(0x0a);
i++;
}
else{
WriteByte(Description[i]);
}
}
WriteByte(0);
ResPos=3;
WriteByte(DescLoc % 256);
WriteByte(DescLoc / 256);
}
for(i=0;i<NumLoops;i++){
ResPos = 5+i*2;
WriteByte(LoopLoc[i] % 256);
WriteByte(LoopLoc[i] / 256);
if(loops[i].mirror==-1){
for(j=0;j<loops[i].NumCels;j++){
ResPos = LoopLoc[i]+1+j*2;
WriteByte(CelLoc[i][j] % 256);
WriteByte(CelLoc[i][j] / 256);
}
}
}
ResourceData.Size=ResSize;
}
//*************************************************
void View::newView()
{
NumLoops = 1;
CurLoop = 0;
CurCel = 0;
loops = new Loop[NumLoops];
loops[CurLoop] = Loop();
loops[CurLoop].numcels(1);
loops[CurLoop].cel(CurCel,1,1,0,false);
Description = "";
}
//*************************************************
void View::fixmirror()
{
int i;
for(i=0;i<NumLoops;i++){
loops[i].mirror1 = -1;
}
for(i=0;i<NumLoops;i++){
for(int j=0;j<NumLoops;j++){
if(i==j)continue;
if(loops[i].mirror == j){
loops[j].mirror1 = i;
}
}
}
}
//*************************************************
void View::printmirror()
{
int i;
for(i=0;i<NumLoops;i++){
printf("%d mirror=%d mirror1=%d\n",i,loops[i].mirror,loops[i].mirror1);
}
}
//*************************************************
void View::insertLoop_before()
//before current
{
int w,h,c,i;
Loop *loops1 = new Loop[NumLoops+1];
for(i=0;i<NumLoops+1;i++){
if(i<CurLoop)
loops1[i] = loops[i];
else if(i>CurLoop)
loops1[i]=loops[i-1];
else{
loops1[i]=Loop();
loops1[i].numcels(1);
if(i>0){
w=loops[0].cels[0].width;
h=loops[0].cels[0].height;
c=loops[0].cels[0].transcol;
}
else{
w=loops[NumLoops-1].cels[0].width;
h=loops[NumLoops-1].cels[0].height;
c=loops[NumLoops-1].cels[0].transcol;
}
loops1[i].cel(0,w,h,c,false);
}
}
delete [] loops;
loops=loops1;
NumLoops++;;
for(i=0;i<NumLoops;i++){
if(loops[i].mirror >= CurLoop){
loops[i].mirror++;
}
}
fixmirror();
}
//*************************************************
void View::insertLoop_after()
//after current
{
int w,h,c,i;
Loop *loops1 = new Loop[NumLoops+1];
for(i=0;i<NumLoops+1;i++){
if(i<=CurLoop)
loops1[i] = loops[i];
else if(i>CurLoop+1)
loops1[i]=loops[i-1];
else{
loops1[i]=Loop();
loops1[i].numcels(1);
if(i>0){
w=loops[0].cels[0].width;
h=loops[0].cels[0].height;
c=loops[0].cels[0].transcol;
}
else{
w=loops[NumLoops-1].cels[0].width;
h=loops[NumLoops-1].cels[0].height;
c=loops[NumLoops-1].cels[0].transcol;
}
loops1[i].cel(0,w,h,c,false);
}
}
delete [] loops;
loops=loops1;
NumLoops++;;
for(i=0;i<NumLoops;i++){
if(loops[i].mirror > CurLoop){
loops[i].mirror++;
}
}
fixmirror();
}
//*************************************************
void View::appendLoop()
//append to end
{
Loop *loops1 = new Loop[NumLoops+1];
for(int i=0;i<NumLoops;i++){
loops1[i] = loops[i];
}
loops1[NumLoops]=Loop();
loops1[NumLoops].numcels(1);
int w=loops[NumLoops-1].cels[0].width;
int h=loops[NumLoops-1].cels[0].height;
int c=loops[NumLoops-1].cels[0].transcol;
loops1[NumLoops].cel(0,w,h,c,false);
delete [] loops;
loops=loops1;
NumLoops++;;
}
//*************************************************
void View::deleteLoop()
//delete CurLoop
{
int i;
for(i=0;i<NumLoops;i++){
if(loops[i].mirror > CurLoop){
loops[i].mirror--;
}
else if(loops[i].mirror == CurLoop){
unsetMirror(i);
}
}
for(i=CurLoop;i<NumLoops-1;i++){
loops[i]=loops[i+1];
}
NumLoops--;
fixmirror();
}
//*************************************************
void View::unsetMirror(int n)
{
int k = loops[n].mirror;
if(k==-1)return;
loops[n].mirror = -1;
for(int i=0;i<loops[n].NumCels;i++){
loops[n].cel(i,1,1,0,false);
loops[n].cels[i].copy(loops[k].cels[i]);
loops[n].cels[i].mirrorh();
}
loops[k].mirror1 = -1;
}
//*************************************************
void View::setMirror(int n,int k)
{
//set loops[n] to mirror k
loops[n].mirror = k;
loops[n].numcels(loops[k].NumCels);
for(int i=0;i<loops[n].NumCels;i++){
loops[n].cel(i,1,1,0,false);
loops[n].cels[i].copy(loops[k].cels[i]);
loops[n].cels[i].mirrorh();
}
loops[k].mirror1 = n;
}
//*************************************************
Cel::Cel(int w,int h,int c,bool m)
{
width = w;
height = h;
transcol = c;
mirror = m;
data = (byte *)malloc(width*2*height);
clear();
}
//*************************************************
Cel::Cel()
{
data = NULL;
width=height=transcol=0;
mirror = false;
}
//*************************************************
void Cel::deinit()
{
if(data)free(data);
data = NULL;
width=height=transcol=0;
mirror = false;
}
//*************************************************
void Cel::setW(int w)
{
int x,y;
if(w==width)return;
byte *data1=(byte *)malloc(w*2*height);
for(y=0;y<height;y++){
for(x=0;x<w*2;x++){
if(x<width*2){
data1[y*w*2+x]=data[y*width*2+x];
}
else{
data1[y*w*2+x]=transcol;
}
}
}
free(data);
data=data1;
width=w;
}
//*************************************************
void Cel::setH(int h){
int x,y;
if(h==height)return;
byte *data1=(byte *)malloc(width*2*h);
for(y=0;y<h;y++){
for(x=0;x<width*2;x++){
if(y<height){
data1[y*width*2+x]=data[y*width*2+x];
}
else{
data1[y*width*2+x]=transcol;
}
}
}
free(data);
data=data1;
height=h;
}
//*************************************************
void Cel::clear()
{
memset(data,transcol,width*2*height);
}
//*************************************************
void Cel::setTrans(int i)
{
transcol=i;
}
//*************************************************
void Cel::right(){
int x,y;
byte k0,k1;
for(y=0;y<height;y++){
k0=data[y*width*2+width*2-1];
k1=data[y*width*2+width*2-2];
for(x=width*2-1;x>1;x-=2){
data[y*width*2+x]=data[y*width*2+x-2];
data[y*width*2+x-1]=data[y*width*2+x-3];
}
data[y*width*2+1]=k0;
data[y*width*2]=k1;
}
}
//*************************************************
void Cel::left(){
int x,y;
byte k0,k1;
for(y=0;y<height;y++){
k0=data[y*width*2];
k1=data[y*width*2+1];
for(x=0;x<width*2-2;x+=2){
data[y*width*2+x]=data[y*width*2+x+2];
data[y*width*2+x+1]=data[y*width*2+x+3];
}
data[y*width*2+x]=k0;
data[y*width*2+x+1]=k1;
}
}
//*************************************************
void Cel::up(){
int x,y;
byte k0;
for(x=0;x<width*2;x++){
k0=data[x];
for(y=0;y<height-1;y++){
data[y*width*2+x]=data[(y+1)*width*2+x];
}
data[y*width*2+x]=k0;
}
}
//*************************************************
void Cel::down(){
int x,y;
byte k0;
for(x=0;x<width*2;x++){
k0=data[(height-1)*width*2+x];
for(y=height-1;y>0;y--){
data[y*width*2+x]=data[(y-1)*width*2+x];
}
data[x]=k0;
}
}
//*************************************************
void Cel::mirrorh(){
int x,y;
byte k0;
for(y=0;y<height;y++){
for(x=0;x<width;x++){
k0=data[y*width*2+x];
data[y*width*2+x]=data[y*width*2+width*2-1-x];
data[y*width*2+width*2-1-x]=k0;
}
}
}
//*************************************************
void Cel::mirrorv(){
int x,y;
byte k0;
for(x=0;x<width*2;x++){
for(y=0;y<height/2;y++){
k0=data[y*width*2+x];
data[y*width*2+x]=data[(height-1-y)*width*2+x];
data[(height-1-y)*width*2+x]=k0;
}
}
}
//*************************************************
void Cel::copy(Cel c){
width = c.width;
height = c.height;
transcol = c.transcol;
mirror = c.mirror;
if(data)free(data);
data = (byte *)malloc(width*2*height);
for(int i=0;i<width*2*height;i++){
data[i]=c.data[i];
}
}
//*************************************************
int Cel::setc(int xn,int yn,byte c0,byte c){
if(xn<0||xn>width-1||yn<0||yn>height-1)return 0;
if(data[width*2*yn+xn*2]==c){
return 0;
}
if(data[width*2*yn+xn*2]==c0){
data[width*2*yn+xn*2]=c;
data[width*2*yn+xn*2+1]=c;
return 1;
}
else{
return 0;
}
}
//*************************************************
void Cel::fill1(int xn,int yn,byte c0,byte c){
if(setc(xn,yn-1,c0,c)==1){
fill1(xn,yn-1,c0,c);
}
if(setc(xn-1,yn,c0,c)==1){
fill1(xn-1,yn,c0,c);
}
if(setc(xn,yn,c0,c)==1){
fill1(xn,yn,c0,c);
}
if(setc(xn+1,yn,c0,c)==1){
fill1(xn+1,yn,c0,c);
}
if(setc(xn,yn+1,c0,c)==1){
fill1(xn,yn+1,c0,c);
}
}
//*************************************************
void Cel::fill(int xn,int yn,byte c){
byte c0;
c0=data[width*2*yn+xn*2];
fill1(xn,yn,c0,c);
}
//**************************************************
Loop::Loop()
{
mirror = mirror1 = -1;
cels = NULL;
CelLoc = NULL;
}
//**************************************************
void Loop::numcels(int n)
{
NumCels = n;
if(cels)
delete [] cels;
if(CelLoc)
delete [] CelLoc;
cels = new Cel[NumCels];
CelLoc = new int[NumCels];
}
void Loop::cel(int n,int w,int h,int c,bool m)
{
cels[n]=Cel(w,h,c,m);
}
//**************************************************
void Loop::insertCel_before(int n)
//insert cell before 'n'
{
Cel *cels1 = new Cel[NumCels+1];
for(int i=0;i<NumCels+1;i++){
if(i<n)
cels1[i] = cels[i];
else if (i>n)
cels1[i] = cels[i-1];
else{
if(i>0)
cels1[i]=Cel(cels[i-1].width,cels[i-1].height,cels[i-1].transcol,cels[i-1].mirror);
else //can't be NumCels==0 !
cels1[i]=Cel(cels[NumCels-1].width,cels[NumCels-1].height,cels[NumCels-1].transcol,cels[NumCels-1].mirror);
cels1[i].clear();
}
}
delete [] cels;
cels = cels1;
NumCels++;
}
//**************************************************
void Loop::insertCel_after(int n)
//insert cell after 'n'
{
Cel *cels1 = new Cel[NumCels+1];
for(int i=0;i<NumCels+1;i++){
if(i<=n)
cels1[i] = cels[i];
else if (i>n+1)
cels1[i] = cels[i-1];
else{
if(i>0)
cels1[i]=Cel(cels[i-1].width,cels[i-1].height,cels[i-1].transcol,cels[i-1].mirror);
else //can't be NumCels==0!
cels1[i]=Cel(cels[NumCels-1].width,cels[NumCels-1].height,cels[NumCels-1].transcol,cels[NumCels-1].mirror);
cels1[i].clear();
}
}
delete [] cels;
cels = cels1;
NumCels++;
}
//**************************************************
void Loop::appendCel()
{
Cel *cels1 = new Cel[NumCels+1];
for(int i=0;i<NumCels;i++){
cels1[i] = cels[i];
}
cels1[NumCels]=Cel(cels[NumCels-1].width,cels[NumCels-1].height,cels[NumCels-1].transcol,cels[NumCels-1].mirror);
cels1[NumCels].clear();
delete [] cels;
cels = cels1;
NumCels++;
}
//**************************************************
void Loop::deleteCel(int n)
{
for(int i=n;i<NumCels-1;i++){
cels[i]=cels[i+1];
}
NumCels--;
}
//**************************************************
void Loop::clear()
{
NumCels=1;
cels[0].clear();
}
//**************************************************

106
src/view.h Normal file
View File

@@ -0,0 +1,106 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef VIEW_H
#define VIEW_H
#include "util.h"
#define MaxLoops 16
#define MaxCels 32
class Cel {
public:
Cel(int w,int h,int c,bool m);
Cel();
int width,height,transcol;
bool mirror;
byte *data;
void setW(int w);
void setH(int h);
void clear();
void setTrans(int i);
void right();
void left();
void up();
void down();
void mirrorh();
void mirrorv();
void copy(Cel c);
void fill(int xn,int yn,byte c);
void deinit();
protected:
int setc(int xn,int yn,byte c0,byte c);
void fill1(int xn,int yn,byte c0,byte c);
};
class Loop {
public:
Loop();
int NumCels;
int LoopLoc;
Cel *cels;
int *CelLoc;
int mirror; //whom I mirror
int mirror1; //who is a mirror of me
void insertCel_before(int n);
void insertCel_after(int n);
void appendCel();
void deleteCel(int n);
void clear();
void numcels(int n);
void cel(int n,int w,int h,int c,bool m);
};
class View {
public:
View();
int NumLoops,CurLoop,CurCel;
bool opened;
string Description;
Loop *loops;
void open();
void init();
int open(int resnum);
int open(char *filename);
void newView();
void ReadViewInfo();
void LoadCel(int loopno,int celno);
void insertLoop_before();
void insertLoop_after();
void appendLoop();
void deleteLoop();
void setMirror(int n,int k);
void unsetMirror(int n);
void fixmirror();
void printmirror();
void save();
int save(char *filename);
int save(int resnum);
};
#endif

1983
src/viewedit.cpp Normal file

File diff suppressed because it is too large Load Diff

251
src/viewedit.h Normal file
View File

@@ -0,0 +1,251 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef VIEWEDIT_H
#define VIEWEDIT_H
#include <qwidget.h>
#include <qlabel.h>
#include <qpushbutton.h>
#include <qlayout.h>
#include <q3listbox.h>
#include <qmessagebox.h>
#include <qlineedit.h>
#include <qradiobutton.h>
#include <q3buttongroup.h>
#include <qcheckbox.h>
#include <q3multilineedit.h>
#include <q3scrollview.h>
#include <qpixmap.h>
#include <qlineedit.h>
#include <qcombobox.h>
#include <qevent.h>
#include <qtimer.h>
//Added by qt3to4:
#include <QCloseEvent>
#include <QShowEvent>
#include <QPaintEvent>
#include <QResizeEvent>
#include <QMouseEvent>
#include <QHideEvent>
#include <QKeyEvent>
#include "util.h"
#include "wutil.h"
#include "view.h"
#include "preview.h"
#include "resources.h"
#define V_DRAW 0
#define V_FILL 1
class ViewEdit;
//********************************************************
class ViewIcon : public QWidget
//small non-editable picture in the description window
{
Q_OBJECT
public:
ViewIcon( QWidget *parent=0, const char *name=0,ViewEdit *v=0);
protected:
ViewEdit *viewedit;
void paintEvent(QPaintEvent *);
};
//********************************************************
class Canvas : public Q3ScrollView
//view drawing area
{
Q_OBJECT
public:
Canvas( QWidget *parent=0, const char *name=0, ViewEdit *v=0);
int x0,y0;
int pixsize;
int cur_w,cur_h;
void DrawCel(int w,int h,byte *data,bool mirror);
void DrawCel(int w,int h,byte *data,bool mirror,int pixsize);
void setSize(int w,int h);
void UpdateCel(int x,int y);
protected:
int CurColor;
QPixmap pixmap;
bool cur_mirror;
byte *data;
ViewEdit *viewedit;
void keyPressEvent( QKeyEvent * );
void viewportMousePressEvent(QMouseEvent* e);
void viewportMouseMoveEvent(QMouseEvent* e);
void drawContents ( QPainter * p,int,int,int,int);
bool focusNextPrevChild ( bool next ) ;
};
//********************************************************
class Description: public QWidget
{
Q_OBJECT
public:
Description( QWidget *parent=0, const char *name=0, ViewEdit *v=0);
public slots:
void set();
void ok_cb();
void cancel_cb();
void getmaxcol();
protected:
ViewIcon *smallview;
ViewEdit *viewedit;
Q3MultiLineEdit *desc;
unsigned int maxcol;
void resizeEvent( QResizeEvent * );
};
//********************************************************
class Animate: public QWidget
{
Q_OBJECT
public:
Animate( QWidget *parent=0, const char *name=0, Preview *p=0, ViewEdit *v=0);
QTimer *timer;
public slots:
void start_stop();
void next_cel();
void closeall();
void fb_cb();
protected:
QLineEdit *delay;
QPushButton *button;
QRadioButton *forward,*backward;
int num;
ViewEdit *viewedit;
Preview *preview;
bool fwd;
};
//********************************************************
class ViewEdit : public QWidget
{
Q_OBJECT
public:
ViewEdit( QWidget *parent=0, const char *name=0,int winnum=0, ResourcesWin *res=0);
Description *description;
Palette *palette;
View *view;
ResourcesWin *resources_win;
int drawing_mode;
bool changed;
void open(int ResNum);
void fillCel(int x,int y,byte color);
void change_mode1(int);
public slots:
void open();
void open_file();
void save_file();
void save_to_game();
void save_to_game_as();
void delete_view();
void undo_cel();
void copy_cel();
void paste_cel();
void next_loop();
void previous_loop();
void first_loop();
void last_loop();
void insert_loop_before();
void insert_loop_after();
void append_loop();
void delete_loop();
void clear_loop();
void change_mirror(int i);
void next_cel();
void previous_cel();
void first_cel();
void last_cel();
void insert_cel_before();
void insert_cel_after();
void append_cel();
void delete_cel();
void clear_cel();
void flipv_cel();
void fliph_cel();
void set_transcolor();
void change_mode(int);
void is_descriptor_cb();
void show_description();
void shift_right();
void shift_left();
void shift_up();
void shift_down();
void zoom_minus();
void zoom_plus();
void change_width_height();
void inc_width();
void dec_width();
void inc_height();
void dec_height();
void animate_cb();
void next_cel_cycle();
void prev_cel_cycle();
protected:
QWidget *transcolor;
QPushButton *edit_descriptor;
QCheckBox *is_descriptor;
Canvas *canvas;
QLabel *loopnum,*celnum;
QLineEdit *width,*height;
QComboBox *mirror_loop;
QRadioButton *view_draw,*view_fill;
Animate *animate;
int ViewNum;
int transcol;
Cel undoCel;
bool undo;
int winnum;
void closeEvent( QCloseEvent *e );
void showEvent( QShowEvent * );
void hideEvent( QHideEvent * );
void open(char *filename);
void save(char *filename);
void do_open();
void deinit();
void display();
void DisplayView();
void DisplayView(int pixsize);
void set_transcolor(int col);
void showmirror();
void showlooppar();
void showcelpar();
int curIndex();
void saveundo();
bool focusNextPrevChild ( bool next ) ;
};
#endif

527
src/words.cpp Normal file
View File

@@ -0,0 +1,527 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
* Almost all of this code was adapted from the Windows AGI Studio
* developed by Peter Kelly.
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include "game.h"
#include "words.h"
#include "menu.h"
#include "wordsedit.h"
#include <stdio.h>
#include <sys/types.h>
#ifndef _WIN32
#include <unistd.h>
#endif
#include <sys/stat.h>
#include <stdlib.h>
#include <ctype.h>
static TWordGroup NewWordGroup[MaxWordGroups];
static int ResPos;
static bool EndOfFileReached;
//***************************************************
WordList::WordList()
{
}
//***************************************************
static byte ReadByte(void)
{
byte ret;
if(ResPos < ResourceData.Size){
ret = ResourceData.Data[ResPos];
ResPos++;
}
else{
ret = 0;
EndOfFileReached = true;
}
return ret;
}
//***************************************************
static int ReadMSLSWord(void)
{
byte MSbyte,LSbyte;
MSbyte = ReadByte();
LSbyte = ReadByte();
return (MSbyte*256 + LSbyte);
}
//***************************************************
int WordList::GetNew_GroupIndex(int GroupNum)
{
int CurIndex;
if (NumGroups > 0){
for(CurIndex = 0; CurIndex < NumGroups; CurIndex++){
if (NewWordGroup[CurIndex].GroupNum == GroupNum){
return CurIndex;
}
}
}
return -1;
}
//************************************************
int WordList::GetWordGroupIndex(int GroupNum)
{
int CurIndex;
if (NumGroups > 0){
for (CurIndex = 0;CurIndex<NumGroups;CurIndex++){
if (WordGroup[CurIndex].GroupNum == GroupNum)
return CurIndex;
}
}
return -1;
}
//************************************************
static string GetWord(string s)
//returns the part of a string before the last ' '
{
int pos = s.find_last_of(' ');
return s.substr(0,pos);
}
static int GetGroupNum(string s)
//returns the number after the last ' ' in a string
{
int pos = s.find_last_of(' ');
return atoi(s.substr(pos+1).c_str());
}
//************************************************
int WordList::read(char *filename)
{
string CurWord,PrevWord;
byte CurByte,CharsFromPrevWord;
int CurIndex,CurAddGroup,GroupIndex,GroupNum;
int LowestRemainingGroup,SecondLowestRemainingGroup,SecondLowestRemainingGroupIndex=0;
int GroupAddOrder[MaxWordGroups];
FILE *fptr=fopen(filename,"rb");
if(fptr==NULL){
menu->errmes("Error opening file %s",filename);
return 1;
}
struct stat buf;
fstat(fileno(fptr),&buf);
int size=buf.st_size;
if(size > MaxResourceSize){
menu->errmes("Error: File %s is too big (>%d bytes)",filename,MaxResourceSize);
return 1;
}
EndOfFileReached = false;
ResourceData.Size=size;
fread(ResourceData.Data,size,1,fptr);
fclose(fptr);
NumGroups = 0;
ResPos = 0;
ResPos = ReadMSLSWord(); //start of words section
PrevWord = "";
do{
CurWord = "";
CharsFromPrevWord = ReadByte();
if (CharsFromPrevWord > PrevWord.length()){
CharsFromPrevWord = PrevWord.length();
}
if (CharsFromPrevWord > 0){
CurWord = PrevWord.substr(0,CharsFromPrevWord);
}
do{
CurByte = ReadByte();
if (CurByte < 0x80)CurWord += (CurByte ^ 0x7f);
}while(CurByte < 0x80 && !EndOfFileReached);
//we must check for end of file, otherwise if the file is invalid, the
//program may read indefinitely.
if(EndOfFileReached){
menu->errmes("Error! Invalid WORDS.TOK file.");
return 1;
}
CurWord += (0x7F ^ (CurByte-0x80));
GroupNum = ReadMSLSWord();
if (CurWord != PrevWord){ //this word different to previous, so add it
//in this way, no duplicates are added
GroupIndex = GetNew_GroupIndex(GroupNum);
if (GroupIndex >= 0){ //group exists
NewWordGroup[GroupIndex].Words.add(CurWord);
}
else{
if (NumGroups >= MaxWordGroups){
menu->errmes("Error ! Too many groups !");
return 1;
}
NumGroups++;
NewWordGroup[NumGroups-1].GroupNum = GroupNum;
NewWordGroup[NumGroups-1].Words = TStringList();
NewWordGroup[NumGroups-1].Words.add(CurWord);
}//group doesn't exist - create new one
PrevWord = CurWord;
}
CurByte = ReadByte();
if (CurByte == 0 && ResPos >= ResourceData.Size-1) EndOfFileReached = true;
else ResPos--;
}while(!EndOfFileReached);
LowestRemainingGroup = -1;
for (CurAddGroup = 0; CurAddGroup < NumGroups; CurAddGroup++){
SecondLowestRemainingGroup = 65536;
for (CurIndex = 0; CurIndex < NumGroups; CurIndex++){
if (NewWordGroup[CurIndex].GroupNum < SecondLowestRemainingGroup &&
NewWordGroup[CurIndex].GroupNum > LowestRemainingGroup){
SecondLowestRemainingGroup = NewWordGroup[CurIndex].GroupNum;
SecondLowestRemainingGroupIndex = CurIndex;
}
}
GroupAddOrder[CurAddGroup] = SecondLowestRemainingGroupIndex;
LowestRemainingGroup = SecondLowestRemainingGroup;
}
for (CurIndex = 0; CurIndex < NumGroups; CurIndex++){
WordGroup[CurIndex].GroupNum = NewWordGroup[GroupAddOrder[CurIndex]].GroupNum;
WordGroup[CurIndex].Words.lfree();
WordGroup[CurIndex].Words.copy(NewWordGroup[GroupAddOrder[CurIndex]].Words);
NewWordGroup[GroupAddOrder[CurIndex]].Words.lfree();
}
return 0;
}
//**************************************************
void WordList::clear()
{
for (int i = 0;i< NumGroups;i++){
WordGroup[i].Words.lfree();
}
NumGroups = 3;
WordGroup[0].GroupNum = 0;
WordGroup[0].Words = TStringList();
WordGroup[0].Words.add("a");
WordGroup[1].GroupNum = 1;
WordGroup[1].Words = TStringList();
WordGroup[1].Words.add("anyword");
WordGroup[2].GroupNum = 9999;
WordGroup[2].Words = TStringList();
WordGroup[2].Words.add("rol");
}
//**************************************************
int WordList::save(char *filename)
{
FILE *fptr;
int CurGroupIndex,NumEmptyWordGroups;
int CurWord,CurChar;
byte CurByte;
int LetterLoc[28];
string ThisWord,PrevWord;
int CurFirstLetter;
char FirstLetter;
int ThisGroupNum;
byte CharsFromPrevWord;
string s;
for(CurGroupIndex=0,NumEmptyWordGroups=0;CurGroupIndex<NumGroups;CurGroupIndex++){
if (WordGroup[CurGroupIndex].Words.num==0){
NumEmptyWordGroups++;
}
}
if (NumEmptyWordGroups > 0){
sprintf(tmp,"Warning: There are %d empty word groups.\nThese will not be saved.",NumEmptyWordGroups);
menu->warnmes(tmp);
}
if((fptr=fopen(filename,"wb"))==NULL){
menu->errmes("Error opening file %s",filename);
return 1;
}
TStringList AllWords = TStringList();
for(CurGroupIndex = 0; CurGroupIndex<NumGroups;CurGroupIndex++){
if (WordGroup[CurGroupIndex].Words.num > 0){
for(CurWord =0;CurWord<WordGroup[CurGroupIndex].Words.num;CurWord++){
s = WordGroup[CurGroupIndex].Words.at(CurWord) + " " + IntToStr(WordGroup[CurGroupIndex].GroupNum);
AllWords.addsorted((char *)s.c_str());
}
}
}
CurByte=0;
fwrite(&CurByte,1,51,fptr);
for (CurFirstLetter = 1;CurFirstLetter <= 26;CurFirstLetter++){
LetterLoc[CurFirstLetter] = 0;
}
FirstLetter = 'a';
LetterLoc[1] = ftell(fptr);
for (CurWord = 0; CurWord < AllWords.num; CurWord++){
ThisWord = GetWord(AllWords.at(CurWord));
if (ThisWord[0] != FirstLetter && ThisWord[0]>=97 && ThisWord[0]<=122){
FirstLetter = ThisWord[0];
LetterLoc[FirstLetter-96] = ftell(fptr);
}
ThisGroupNum = GetGroupNum(AllWords.at(CurWord));
//work out # chars from prev word
CharsFromPrevWord = 0;
CurChar = 0;
bool FinishedComparison = false;
do{
if(CurChar < (int)ThisWord.length() && (int)PrevWord.length() > CurChar && PrevWord[CurChar] == ThisWord[CurChar])
CharsFromPrevWord++;
else FinishedComparison=true;
CurChar++;
}while(! FinishedComparison);
if (CharsFromPrevWord >= ThisWord.length()){
CharsFromPrevWord = ThisWord.length()-1;
}
//write # chars from prev word
fwrite(&CharsFromPrevWord,1,1,fptr);
PrevWord = ThisWord;
ThisWord = ThisWord.substr( CharsFromPrevWord,ThisWord.length()-CharsFromPrevWord);
if (ThisWord.length() > 1){
for(CurChar =0;CurChar <(int)ThisWord.length()-1;CurChar++){
CurByte = 0x7f ^ ThisWord[CurChar];
fwrite(&CurByte,1,1,fptr);
}
}
CurByte = 0x80 + (0x7f ^ ThisWord[ThisWord.length()-1]);
fwrite(&CurByte,1,1,fptr);
//write group number
CurByte = ThisGroupNum / 256;
fwrite(&CurByte,1,1,fptr);
CurByte = ThisGroupNum % 256;
fwrite(&CurByte,1,1,fptr);
}
CurByte = 0;
fwrite(&CurByte,1,1,fptr);
fseek(fptr,0,SEEK_SET);
for(CurFirstLetter = 1;CurFirstLetter <=26;CurFirstLetter++){
CurByte = LetterLoc[CurFirstLetter] / 256;
fwrite(&CurByte,1,1,fptr);
CurByte = LetterLoc[CurFirstLetter] % 256;
fwrite(&CurByte,1,1,fptr);
}
AllWords.lfree();
fclose(fptr);
return 0;
}
//**************************************************
int WordList::add_group(int num)
{
int i;
for (i = 0;i< NumGroups;i++){
if(num == WordGroup[i].GroupNum){
menu->errmes("Group %d already exists.",num);
return -1;
}
if(WordGroup[i].GroupNum > num){
break;
}
}
NumGroups++;
for(int k=NumGroups;k>i;k--){
WordGroup[k]=WordGroup[k-1];
}
WordGroup[i].Words = TStringList();
WordGroup[i].GroupNum = num;
return i;
}
//**************************************************
int WordList::delete_group(int num)
{
for(int i=num;i<NumGroups-1;i++){
WordGroup[i]=WordGroup[i+1];
}
NumGroups--;
return 0;
}
//**************************************************
int WordList::delete_word(char *word,int SelectedGroup)
{
if(SelectedGroup<0)return -1;
for(int k=0;k<WordGroup[SelectedGroup].Words.num;k++){
if(!strcmp(word,WordGroup[SelectedGroup].Words.at(k).c_str())){
WordGroup[SelectedGroup].Words.del(k);
return k;
}
}
return -1;
}
//**************************************************
int WordList::change_number(int oldnum, int newnum)
{
int i;
for (i = 0;i< NumGroups;i++){
if(newnum == WordGroup[i].GroupNum){
menu->errmes("Group %d already exists.",newnum);
return -1;
}
if(WordGroup[i].GroupNum > newnum){
break;
}
}
TStringList cur_g = TStringList();
cur_g.copy(WordGroup[oldnum].Words);
if(oldnum < i){
i--;
for(int k=oldnum;k<i;k++){
WordGroup[k]=WordGroup[k+1];
}
}
else{
for(int k=oldnum;k>i;k--){
WordGroup[k]=WordGroup[k-1];
}
}
WordGroup[i].Words = cur_g;
WordGroup[i].GroupNum = newnum;
return i;
}
//************************************************************
bool WordList::GroupExists(int GroupNum)
{
int CurGroupIndex;
if (NumGroups > 0){
for (CurGroupIndex=0;CurGroupIndex<NumGroups;CurGroupIndex++){
if(WordGroup[CurGroupIndex].GroupNum == GroupNum)return true;
}
}
return false;
}
//************************************************************
bool WordList::InsertWordGroup(int GroupNum)
{
int CurGroupIndex,InsertPosition=0;
bool InsertPositionFound;
if (NumGroups >= MaxWordGroups){
menu->errmes("Error! Too many groups (max %d).",MaxWordGroups);
return false;
}
CurGroupIndex = 0;
InsertPositionFound = false;
do{
if (WordGroup[CurGroupIndex].GroupNum > GroupNum){
InsertPosition = CurGroupIndex;
InsertPositionFound = true;
}
else CurGroupIndex++;
}while(!InsertPositionFound && (CurGroupIndex < NumGroups));
if (CurGroupIndex > NumGroups - 1)InsertPosition = NumGroups;
WordGroup[NumGroups].Words = TStringList();
if (NumGroups > 0){
for (CurGroupIndex = NumGroups - 1;CurGroupIndex>=InsertPosition;CurGroupIndex--){
WordGroup[CurGroupIndex+1].GroupNum = WordGroup[CurGroupIndex].GroupNum;
WordGroup[CurGroupIndex+1].Words.lfree();
WordGroup[CurGroupIndex+1].Words.copy(WordGroup[CurGroupIndex].Words);
}
}
NumGroups++;
WordGroup[InsertPosition].GroupNum = GroupNum;
WordGroup[InsertPosition].Words.lfree();
return true;
}
//************************************************************
int WordList::GroupIndexOfWord(string word)
//returns the group index of the group containing the specified word}
{
for (int i = 0;i< NumGroups;i++){
for(int k = 0;k<WordGroup[i].Words.num;k++){
if(WordGroup[i].Words.at(k) == word){
return i;
}
}
}
return -1;
}
//************************************************************
void WordList::merge(const WordList& NewWordList)
{
int CurIndex,CurWord,GroupIndex,NumWordsAdded,GroupIndexOfExistingWord;
string ThisWord;
WhatToDoWithExistingWords = AskUser;
if(NewWordList.NumGroups==0)return;
NumWordsAdded = 0;
for (CurIndex = 0;CurIndex<NewWordList.NumGroups;CurIndex++){
if (!GroupExists(NewWordList.WordGroup[CurIndex].GroupNum))
InsertWordGroup(NewWordList.WordGroup[CurIndex].GroupNum);
GroupIndex = GetWordGroupIndex(NewWordList.WordGroup[CurIndex].GroupNum);
if (GroupIndex >= 0 && NewWordList.WordGroup[CurIndex].Words.num > 0){
for (CurWord= 0;CurWord<NewWordList.WordGroup[CurIndex].Words.num;CurWord++){
GroupIndexOfExistingWord = GroupIndexOfWord(NewWordList.WordGroup[CurIndex].Words.at(CurWord));
if ((GroupIndexOfExistingWord < 0) || ((GroupIndexOfExistingWord >= 0) && (OKToReplaceWord(NewWordList.WordGroup[CurIndex].Words.at(CurWord),WordGroup[GroupIndexOfExistingWord].GroupNum,WordGroup[GroupIndex].GroupNum)))){
delete_word((char *)NewWordList.WordGroup[CurIndex].Words.at(CurWord).c_str(),GroupIndexOfExistingWord);
WordGroup[GroupIndex].Words.addsorted(NewWordList.WordGroup[CurIndex].Words.at(CurWord));
NumWordsAdded++;
}
}
}//{if (GroupIndex >= 0) and (NewWordList.WordGroup[CurIndex].Words.Count > 0)}
}
}
//************************************************************
bool WordList::OKToReplaceWord(string TheWord,int OldGroupNum, int NewGroupNum)
{
if (WhatToDoWithExistingWords == AlwaysReplace)return true;
if (WhatToDoWithExistingWords == NeverReplace)return false;
if (OldGroupNum == NewGroupNum)return true;
ReplaceWord *ask = new ReplaceWord(TheWord,OldGroupNum,NewGroupNum);
int AskResult = ask->exec();
if (AskResult == mrYesToAll)WhatToDoWithExistingWords = AlwaysReplace;
if (AskResult == mrNoToAll)WhatToDoWithExistingWords = NeverReplace;
if (AskResult == mrYes || AskResult == mrYesToAll)return true;
else return false;
}
//************************************************************

65
src/words.h Normal file
View File

@@ -0,0 +1,65 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef WORDS_H
#define WORDS_H
#include "util.h"
typedef struct{
TStringList Words;
int GroupNum;
}TWordGroup;
#define MaxGroupNum 65535
#define MaxWordGroups 10000
class WordList
{
public:
WordList();
TWordGroup WordGroup[MaxWordGroups];
int NumGroups;
char WhatToDoWithExistingWords;
void clear();
int read(char *filename);
int save(char *filename);
int add_group(int num);
int delete_group(int num);
int delete_word(char *word,int SelectedGroup);
int change_number(int oldnum, int newnum);
int GetWordGroupIndex(int GroupNum);
int GetNew_GroupIndex(int GroupNum);
void merge(const WordList& w);
int GroupIndexOfWord(string word);
bool OKToReplaceWord(string TheWord,int OldGroupNum, int NewGroupNum);
bool InsertWordGroup(int GroupNum);
bool GroupExists(int GroupNum);
};
#define mrYes 1
#define mrYesToAll 2
#define mrNo 3
#define mrNoToAll 4
#define AskUser 0
#define AlwaysReplace 1
#define NeverReplace 2
#endif

904
src/wordsedit.cpp Normal file
View File

@@ -0,0 +1,904 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include "game.h"
#include "words.h"
#include "menu.h"
#include "wordsedit.h"
#include "resources.h"
#include <stdio.h>
#include <sys/types.h>
#ifndef _WIN32
#include <unistd.h>
#endif
#include <sys/stat.h>
#include <stdlib.h>
#include <ctype.h>
#include <qapplication.h>
#include <qsplitter.h>
#include <q3frame.h>
#include <qmessagebox.h>
#include <q3filedialog.h>
#include <qstringlist.h>
//Added by qt3to4:
#include <Q3HBoxLayout>
#include <QCloseEvent>
#include <Q3BoxLayout>
#include <QShowEvent>
#include <QLabel>
#include <Q3PopupMenu>
#include <QHideEvent>
#include <Q3VBoxLayout>
WordsEdit::WordsEdit( QWidget *parent, const char *name, int win_num, ResourcesWin *res )
: QWidget( parent, name ,Qt::WDestructiveClose )
{
setCaption("WORDS.TOK Editor");
wordlist = new WordList();
winnum = win_num;
resources_win = res;
wordsfind = NULL;
Q3PopupMenu *file = new Q3PopupMenu( this );
Q_CHECK_PTR( file );
file->insertItem( "New", this, SLOT(new_file()) );
file->insertItem( "Open", this, SLOT(open_file()) );
file->insertItem( "Merge", this, SLOT(merge_file()) );
file->insertItem( "Save", this, SLOT(save_file()) );
file->insertItem( "Save As", this, SLOT(save_as_file()) );
file->insertSeparator();
file->insertItem( "Close", this, SLOT(close()) );
Q3PopupMenu *words = new Q3PopupMenu( this );
Q_CHECK_PTR( words );
words->insertItem( "Add word group", this, SLOT(add_group_cb()) );
words->insertItem( "Delete word group", this, SLOT(delete_group_cb()) );
words->insertItem( "Change group number", this, SLOT(change_group_number_cb()) );
words->insertSeparator();
words->insertItem( "Add word", this, SLOT(add_word_cb()) );
words->insertItem( "Delete word", this, SLOT(delete_word_cb()) );
words->insertSeparator();
words->insertItem( "Count word groups", this, SLOT(count_groups_cb()) );
words->insertItem( "Count words", this, SLOT(count_words_cb()) );
words->insertItem( "&Find...", this, SLOT(find_cb()) , Qt::CTRL+Qt::Key_F);
QMenuBar *menu = new QMenuBar(this);
Q_CHECK_PTR( menu );
menu->insertItem( "File", file );
menu->insertItem( "Words", words );
menu->setSeparator( QMenuBar::InWindowsStyle );
Q3BoxLayout *all = new Q3VBoxLayout(this,10);
QSplitter *split = new QSplitter(Qt::Horizontal,this);
QWidget *left = new QWidget(split);
Q3BoxLayout *lgroup = new Q3VBoxLayout(left,4);
QLabel *labelgroup = new QLabel("Word groups",left,"Word groups");
labelgroup->setAlignment(Qt::AlignCenter);
lgroup->addWidget(labelgroup);
listgroup = new Q3ListBox(left);
listgroup->setColumnMode (1);
listgroup->setMinimumSize(200,300);
connect( listgroup, SIGNAL(highlighted(int)), SLOT(select_group(int)) );
connect( listgroup, SIGNAL(selected(int)), SLOT(select_group(int)) );
lgroup->addWidget(listgroup);
QWidget *right = new QWidget(split);
Q3BoxLayout *lwords = new Q3VBoxLayout(right,4);
labelword = new QLabel("Word group",right,"Word group");
labelword->setAlignment(Qt::AlignCenter);
lwords->addWidget(labelword);
listwords = new Q3ListBox(right);
listwords->setColumnMode (1);
listwords->setMinimumSize(200,300);
connect( listwords, SIGNAL(highlighted(int)), SLOT(select_word(int)) );
connect( listwords, SIGNAL(selected(int)), SLOT(select_word(int)) );
lwords->addWidget(listwords);
lineword = new QLineEdit(right);
lineword->setEnabled(false);
connect( lineword, SIGNAL(returnPressed()), SLOT(do_add_word()) );
lwords->addWidget(lineword);
all->addWidget(split);
Q3BoxLayout *buttons = new Q3HBoxLayout(all,20);
add_group = new QPushButton("Add group",this);
connect( add_group, SIGNAL(clicked()), SLOT(add_group_cb()) );
buttons->addWidget(add_group);
delete_group = new QPushButton("Delete group",this);
connect( delete_group, SIGNAL(clicked()), SLOT(delete_group_cb()) );
buttons->addWidget(delete_group);
add_word = new QPushButton("Add word",this);
connect( add_word, SIGNAL(clicked()), SLOT(add_word_cb()) );
buttons->addWidget(add_word);
delete_word = new QPushButton("Delete word",this);
connect( delete_word, SIGNAL(clicked()), SLOT(delete_word_cb()) );
buttons->addWidget(delete_word);
Q3BoxLayout *buttons1 = new Q3HBoxLayout(all,20);
change_group_number = new QPushButton("&Change group number",this);
connect( change_group_number, SIGNAL(clicked()), SLOT(change_group_number_cb()) );
buttons1->addWidget(change_group_number);
find = new QPushButton("Find",this);
connect( find, SIGNAL(clicked()), SLOT(find_cb()) );
buttons1->addWidget(find);
adjustSize();
changed=false;
filename="";
SelectedGroup=0;
FindLastGroup = FindLastWord = -1;
}
//********************************************************
void WordsEdit::deinit()
{
delete wordlist;
winlist[winnum].type=-1;
if(window_list && window_list->isVisible())window_list->draw();
}
//*********************************************
void WordsEdit::hideEvent( QHideEvent * )
{
if(wordsfind){
wordsfind->close(true);
wordsfind=NULL;
}
if(window_list && window_list->isVisible())window_list->draw();
}
//*********************************************
void WordsEdit::showEvent( QShowEvent * )
{
if(window_list && window_list->isVisible())window_list->draw();
}
//********************************************************
void WordsEdit::closeEvent( QCloseEvent *e )
{
if(changed){
switch ( QMessageBox::warning( this, "WORDS.TOK edit",
"Save changes to WORDS.TOK ?",
"Yes",
"No",
"Cancel",
0, 2) ) {
case 0: // yes
save_file() ;
deinit();
e->accept();
// else
// e->ignore();
break;
case 1: // no
deinit();
e->accept();
break;
default: // cancel
e->ignore();
break;
}
}
else{
deinit();
e->accept();
}
}
//********************************************************
void WordsEdit::update_all()
{
listgroup->clear();
listwords->clear();
if (wordlist->NumGroups > 0){
for (int i = 0;i< wordlist->NumGroups;i++){
sprintf(tmp,"%d. ",wordlist->WordGroup[i].GroupNum);
for(int k=0;k<wordlist->WordGroup[i].Words.num;k++){
if(k>0)strcat(tmp," | ");
strcat(tmp,wordlist->WordGroup[i].Words.at(k).c_str());
}
QString str = tmp;
listgroup->insertItem( str );
}
}
show();
changed=false;
}
//********************************************************
void WordsEdit::open(char *filenam)
{
int ret = wordlist->read(filenam);
if(ret)return ;
filename = filenam;
update_all();
return;
}
//********************************************************
void WordsEdit::open()
{
sprintf(tmp,"%s/words.tok",game->dir.c_str());
open(tmp);
}
//********************************************************
void WordsEdit::add_group_cb(void)
{
AskNumber *addgroup = new AskNumber(0,0,"Add group","Enter group number:");
if(!addgroup->exec())return;
int i;
QString str = addgroup->num->text();
int num = atoi((char *)str.latin1());
if(num < 0 || num > 65535){
menu->errmes("Wordsedit","You must enter an integer from 0 to 65535.");
return;
}
if((i=wordlist->add_group(num))==-1)return;
str.sprintf("%d. ",num);
listgroup->insertItem(str,i);
listgroup->setCurrentItem(i);
changed=true;
}
//********************************************************
void WordsEdit::delete_group_cb(void)
{
int rm = listgroup->currentItem();
if(rm != -1){
wordlist->delete_group(rm);
listgroup->removeItem(rm);
if(wordlist->NumGroups>0){
listgroup->setCurrentItem(rm);
select_group(rm);
}
else listwords->clear();
changed=true;
}
}
//********************************************************
void WordsEdit::print_group(int curgroup)
{
sprintf(tmp,"%d. ",wordlist->WordGroup[curgroup].GroupNum);
for(int i=0;i<wordlist->WordGroup[curgroup].Words.num;i++){
if(i>0)strcat(tmp," | ");
strcat(tmp,wordlist->WordGroup[curgroup].Words.at(i).c_str());
}
}
//********************************************************
void WordsEdit::update_group(int curgroup)
{
print_group(curgroup);
listgroup->changeItem(tmp,curgroup);
}
//********************************************************
void WordsEdit::delete_word_cb(void)
{
QString str = lineword->text();
char *word = (char *)str.latin1();
int k=wordlist->delete_word(word,SelectedGroup);
if(k!=-1){
lineword->setText("");
listwords->removeItem(k);
update_group(SelectedGroup);
changed=true;
return;
}
}
//********************************************************
void WordsEdit::change_group_number_cb(void)
{
AskNumber *newnumber = new AskNumber(0,0,"Change group number","Enter group number:");
if(!newnumber->exec())return;
int i;
QString str = newnumber->num->text();
int num = atoi((char *)str.latin1());
if(num < 0 || num > 65535){
menu->errmes("Wordsedit","You must enter an integer from 0 to 65535.");
return;
}
int currentgroup = listgroup->currentItem();
if((i=wordlist->change_number(currentgroup,num))==-1)return ;
listgroup->removeItem(currentgroup);
listgroup->insertItem("",i);
update_group(i);
changed=true;
}
//********************************************************
void WordsEdit::find_cb(void)
{
if(wordsfind == NULL){
wordsfind = new WordsFind(0,0,this);
}
wordsfind->show();
wordsfind->find_field->setFocus();
}
//********************************************************
int WordsEdit::find_down(char *word)
{
for (int i = FindLastGroup;i< wordlist->NumGroups;i++){
for(int k = FindLastWord;k<wordlist->WordGroup[i].Words.num;k++){
if(!strcmp(wordlist->WordGroup[i].Words.at(k).c_str(),word)){
FindLastWord = k;
FindLastGroup = i;
return 1;
}
}
FindLastWord=0;
}
FindLastGroup = wordlist->NumGroups-1;
FindLastWord = wordlist->WordGroup[FindLastGroup].Words.num-1;
return 0;
}
//********************************************************
int WordsEdit::find_up(char *word)
{
for (int i = FindLastGroup;i>= 0;i--){
for(int k = FindLastWord;k>=0;k--){
if(!strcmp(wordlist->WordGroup[i].Words.at(k).c_str(),word)){
FindLastWord = k;
FindLastGroup = i;
return 1;
}
}
if(i>0)FindLastWord=wordlist->WordGroup[i-1].Words.num-1;
}
FindLastWord=0;
FindLastGroup=0;
return 0;
}
//********************************************************
void WordsEdit::select_group(int num)
{
QString str;
str.sprintf("Word group %d",wordlist->WordGroup[num].GroupNum);
labelword->setText(str);
SelectedGroup = num;
listwords->clear();
for(int k=0;k<wordlist->WordGroup[num].Words.num;k++){
string str2 = wordlist->WordGroup[num].Words.at(k);
const char *str1 = str2.c_str();
listwords->insertItem(str1);
}
delete_word->setEnabled(false);
lineword->setText("");
lineword->setEnabled(false);
listwords->show();
}
//********************************************************
void WordsEdit::select_word(int num)
{
lineword->setText(wordlist->WordGroup[SelectedGroup].Words.at(num).c_str());
delete_word->setEnabled(true);
}
//********************************************************
void WordsEdit::add_word_cb(void)
{
lineword->setEnabled(true);
lineword->setText("new word");
lineword->selectAll();
lineword->setFocus();
}
//********************************************************
void WordsEdit::do_add_word(void)
{
QString str = lineword->text();
char *word = (char *)str.latin1();
FindLastWord = 0;
FindLastGroup = 0;
int curgroup = listgroup->currentItem();
if(find_down(word)){
sprintf(tmp,"This word already exists (in group %d).\nDo you wish to remove this occurance and add it to this group ?",wordlist->WordGroup[FindLastGroup].GroupNum);
switch( QMessageBox::information( this, "Remove duplicate word ?",
tmp,
"Yes", "No",
0, // Enter == button 0
1 ) ) { // Escape == button 1
case 0: //yes
wordlist->WordGroup[FindLastGroup].Words.del(FindLastWord);
update_group(FindLastGroup);
changed=true;
break;
case 1: //no
return;
}
}
wordlist->WordGroup[curgroup].Words.addsorted(word);
changed=true;
select_group(curgroup);
update_group(curgroup);
}
//********************************************************
void WordsEdit::count_groups_cb(void)
{
sprintf(tmp,"There are %d word groups.",wordlist->NumGroups);
QMessageBox::information( this, "AGI studio",
tmp,
"OK",
0, 0);
}
//********************************************************
void WordsEdit::count_words_cb(void)
{
int n = 0;
for (int i = 0;i< wordlist->NumGroups;i++){
n+=wordlist->WordGroup[i].Words.num;
}
sprintf(tmp,"There are %d words.",n);
QMessageBox::information( this, "AGI studio",
tmp,
"OK",
0, 0);
}
//********************************************************
void WordsEdit::open_file()
{
Q3FileDialog *f = new Q3FileDialog(0,"Open",true);
const char *filters[] = {"words.tok","*.tok","All files (*)",NULL};
f->setFilters(filters);
f->setCaption("Open");
f->setMode(Q3FileDialog::ExistingFile);
f->setDir(game->dir.c_str());
if ( f->exec() == QDialog::Accepted ) {
if ( !f->selectedFile().isEmpty() )
open((char *)f->selectedFile().latin1());
}
}
//********************************************************
void WordsEdit::save_as_file()
{
Q3FileDialog *f = new Q3FileDialog(0,"Save",true);
const char *filters[] = {"words.tok","*.tok","All files (*)",NULL};
f->setFilters(filters);
f->setCaption("Save");
f->setMode(Q3FileDialog::AnyFile);
f->setDir(game->dir.c_str());
if ( f->exec() == QDialog::Accepted ) {
if ( !f->selectedFile().isEmpty() )
save((char *)f->selectedFile().latin1());
}
}
//********************************************************
void WordsEdit::new_file()
{
setCaption("WORDS.TOK Editor");
wordlist->clear();
listgroup->clear();
listwords->clear();
for(int i=0;i<3;i++){
print_group(i);
listgroup->insertItem(tmp);
}
filename="";
}
//********************************************************
void WordsEdit::save(char *filename)
{
if (wordlist->NumGroups == 0){
menu->errmes("Wordsedit","Error: Could not save the file as there are no word groups.");
return;
}
if(!wordlist->save(filename)){
changed=false;
}
}
//********************************************************
void WordsEdit::save_file()
{
if(filename!="")
save((char *)filename.c_str());
else
save_as_file();
}
//********************************************************
void WordsEdit::merge_file()
{
WordList w = WordList();
Q3FileDialog *f = new Q3FileDialog(0,"Open",true);
const char *filters[] = {"words.tok","*.tok","All files (*)",NULL};
f->setFilters(filters);
f->setCaption("Open");
f->setMode(Q3FileDialog::ExistingFile);
f->setDir(game->dir.c_str());
if ( f->exec() == QDialog::Accepted ) {
if ( !f->selectedFile().isEmpty() ){
int ret = w.read((char *)f->selectedFile().latin1());
if(ret)return ;
wordlist->merge(w);
update_all();
}
}
}
//********************************************************
WordsFind::WordsFind( QWidget *parent, const char *name , WordsEdit *w)
: QWidget( parent, name )
{
wordsedit = w;
wordlist=w->wordlist;
setCaption("Find");
Q3BoxLayout *all = new Q3VBoxLayout(this,10);
Q3BoxLayout *txt = new Q3HBoxLayout(all,4);
QLabel *label = new QLabel("Find what:",this);
txt->addWidget(label);
find_field = new QLineEdit(this);
find_field->setMinimumWidth(200);
connect( find_field, SIGNAL(returnPressed()), SLOT(find_first_cb()) );
txt->addWidget(find_field);
Q3BoxLayout *left1 = new Q3HBoxLayout(all,10);
Q3ButtonGroup *direction = new Q3ButtonGroup(2,Qt::Vertical,"Dir",this);
up = new QRadioButton("Up",direction);
up->setChecked(false);
down = new QRadioButton("Down",direction);
down->setChecked(true);
left1->addWidget(direction);
Q3ButtonGroup *from = new Q3ButtonGroup(2,Qt::Vertical,"From",this);
start = new QRadioButton("Start",from);
start->setChecked(true);
current = new QRadioButton("Current",from);
current->setChecked(false);
left1->addWidget(from);
Q3ButtonGroup *type = new Q3ButtonGroup(2,Qt::Vertical,"Match",this);
exact = new QRadioButton("Exact",type);
exact->setChecked(false);
substring = new QRadioButton("Substr",type);
substring->setChecked(true);
left1->addWidget(type);
Q3BoxLayout *right = new Q3VBoxLayout(left1,5);
find_first = new QPushButton("Find",this);
right->addWidget(find_first);
connect( find_first, SIGNAL(clicked()), SLOT(find_first_cb()) );
find_next = new QPushButton("Find next",this);
connect( find_next, SIGNAL(clicked()), SLOT(find_next_cb()) );
right->addWidget(find_next);
cancel = new QPushButton("Cancel",this);
connect( cancel, SIGNAL(clicked()), SLOT(cancel_cb()) );
right->addWidget(cancel);
adjustSize();
FindLastWord=-1;
FindLastGroup=-1;
}
//********************************************************
int WordsFind::find_down(char *word)
{
bool sub = substring->isChecked();
for (int i = FindLastGroup;i< wordlist->NumGroups;i++){
for(int k = FindLastWord;k<wordlist->WordGroup[i].Words.num;k++){
if((sub && strstr(wordlist->WordGroup[i].Words.at(k).c_str(),word))||
!strcmp(wordlist->WordGroup[i].Words.at(k).c_str(),word)){
FindLastWord = k;
FindLastGroup = i;
return 1;
}
}
FindLastWord=0;
}
FindLastGroup = wordlist->NumGroups-1;
FindLastWord = wordlist->WordGroup[FindLastGroup].Words.num-1;
return 0;
}
//********************************************************
int WordsFind::find_up(char *word)
{
bool sub = substring->isChecked();
for (int i = FindLastGroup;i>= 0;i--){
for(int k = FindLastWord;k>=0;k--){
if((sub && strstr(wordlist->WordGroup[i].Words.at(k).c_str(),word))||
!strcmp(wordlist->WordGroup[i].Words.at(k).c_str(),word)){
FindLastWord = k;
FindLastGroup = i;
return 1;
}
}
if(i>0)FindLastWord=wordlist->WordGroup[i-1].Words.num-1;
}
FindLastWord=0;
FindLastGroup=0;
return 0;
}
//********************************************************
void WordsFind::find_first_cb()
{
int ret;
QString str = find_field->text();
char *word = (char *)str.latin1();
if(down->isChecked()){
if(start->isChecked()){
FindLastGroup=0;
FindLastWord=0;
}
else{
if(wordsedit->listgroup->currentItem()!=-1)
FindLastGroup=wordsedit->listgroup->currentItem();
else
FindLastGroup=0;
if(wordsedit->listwords->currentItem()!=-1)
FindLastWord=wordsedit->listwords->currentItem();
else
FindLastWord=0;
}
ret = find_down(word);
}
else{
if(start->isChecked()){
FindLastGroup=wordlist->NumGroups -1;
FindLastWord = wordlist->WordGroup[FindLastGroup].Words.num-1;
}
else{
if(wordsedit->listgroup->currentItem()!=-1)
FindLastGroup=wordsedit->listgroup->currentItem();
else
FindLastGroup=wordlist->NumGroups -1;
if(wordsedit->listwords->currentItem()!=-1)
FindLastWord=wordsedit->listwords->currentItem();
else
FindLastWord=wordlist->WordGroup[FindLastGroup].Words.num-1;
}
ret = find_up(word);
}
if(ret){
wordsedit->listgroup->setCurrentItem(FindLastGroup);
wordsedit->listwords->setCurrentItem(FindLastWord);
}
else{
menu->errmes("Find","'%s' not found !",word);
}
}
//********************************************************
void WordsFind::find_next_cb()
{
int ret;
QString str = find_field->text();
char *word = (char *)str.latin1();
if(FindLastGroup==-1||FindLastWord==-1){
find_first_cb();
return;
}
if(down->isChecked()){
if(FindLastWord+1 >= wordlist->WordGroup[FindLastGroup].Words.num){
if(FindLastGroup+1 >= wordlist->NumGroups){
menu->errmes("Find","'%s' not found !",word);
return ;
}
else{
FindLastWord = 0;
FindLastGroup++;
}
}
else{
FindLastWord++;
}
ret = find_down(word);
}
else{
if(FindLastWord -1 < 0){
if(FindLastGroup-1 < 0){
menu->errmes("Find","'%s' not found !",word);
return;
}
else{
FindLastGroup--;
FindLastWord = wordlist->WordGroup[FindLastGroup].Words.num-1;
}
}
else{
FindLastWord--;
}
ret = find_up(word);
}
if(ret){
wordsedit->listgroup->setCurrentItem(FindLastGroup);
wordsedit->listwords->setCurrentItem(FindLastWord);
}
else{
menu->errmes("Find","'%s' not found !",word);
}
}
//************************************************
void WordsFind::cancel_cb()
{
hide();
}
//************************************************
ReplaceWord::ReplaceWord(string word,int OldGroupNum, int NewGroupNum, QWidget *parent, QString name )
: QDialog( parent, name, TRUE ,Qt::WDestructiveClose)
{
setCaption("Replace word");
Q3BoxLayout *all = new Q3VBoxLayout(this,10);
sprintf(tmp,"The word %s already exists in group %d of the currently open file.",word.c_str(),OldGroupNum);
QLabel *l1 = new QLabel(tmp,this);
all->add(l1);
sprintf(tmp,"Do you wish to replace it with the occurance in the merge file (group %d )?",NewGroupNum);
QLabel *l2 = new QLabel(tmp,this);
all->add(l2);
Q3BoxLayout *b = new Q3HBoxLayout(all,10);
QPushButton *yes = new QPushButton( "Yes", this );
connect( yes, SIGNAL(clicked()), SLOT(yes() ));
b->addWidget(yes);
QPushButton *yes_to_all = new QPushButton( "Yes to all", this );
connect( yes_to_all, SIGNAL(clicked()), SLOT(yes_to_all() ));
b->addWidget(yes_to_all);
QPushButton *no = new QPushButton( "No", this );
connect( no, SIGNAL(clicked()), SLOT(no() ));
b->addWidget(no);
QPushButton *no_to_all = new QPushButton( "No to all", this );
connect( no_to_all, SIGNAL(clicked()), SLOT(no_to_all() ));
b->addWidget(no_to_all);
adjustSize();
}
//************************************************
void ReplaceWord::yes()
{
done(mrYes);
}
//************************************************
void ReplaceWord::yes_to_all()
{
done(mrYesToAll);
}
//************************************************
void ReplaceWord::no()
{
done(mrNo);
}
//************************************************
void ReplaceWord::no_to_all()
{
done(mrNoToAll);
}
//************************************************

141
src/wordsedit.h Normal file
View File

@@ -0,0 +1,141 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef WORDSEDIT_H
#define WORDSEDIT_H
#include <qwidget.h>
#include <qlabel.h>
#include <qpushbutton.h>
#include <qlayout.h>
#include <q3listbox.h>
#include <qmessagebox.h>
#include <qlineedit.h>
#include <qradiobutton.h>
#include <q3buttongroup.h>
#include <qevent.h>
//Added by qt3to4:
#include <QShowEvent>
#include <QHideEvent>
#include <QCloseEvent>
#include "util.h"
#include "wutil.h"
#include "words.h"
#include "resources.h"
class WordsFind;
//******************************************************
class WordsEdit : public QWidget
{
Q_OBJECT
public:
WordsEdit( QWidget *parent=0, const char *name=0, int winnum=0, ResourcesWin *res=0);
Q3ListBox *listgroup,*listwords;
ResourcesWin *resources_win;
WordList *wordlist;
void open();
public slots:
void add_group_cb(void);
void delete_group_cb(void);
void add_word_cb(void);
void do_add_word(void);
void delete_word_cb(void);
void change_group_number_cb(void);
void find_cb(void);
void select_group(int);
void select_word(int);
void update_group(int);
void count_groups_cb(void);
void count_words_cb(void);
void new_file();
void open_file();
void merge_file();
void save_file();
void save_as_file();
protected:
void open(char *);
void save(char *);
void deinit();
int winnum;
QLabel *labelword;
QLineEdit *lineword;
QPushButton *add_group,*delete_group,*add_word,*delete_word,
*change_group_number,*find;
WordsFind *wordsfind;
bool changed;
string filename;
int FindLastGroup,FindLastWord;
int SelectedGroup;
int find_down(char *word);
int find_up(char *word);
void print_group(int curgroup);
void add_group_ok_cb();
void change_group_ok_cb();
void closeEvent( QCloseEvent *e );
void showEvent( QShowEvent * );
void hideEvent( QHideEvent * );
void update_all();
};
//******************************************************
class WordsFind : public QWidget
{
Q_OBJECT
public:
WordsFind( QWidget *parent=0, const char *name=0,WordsEdit *w=0);
void open();
QLineEdit *find_field;
bool first;
public slots:
void find_next_cb();
void find_first_cb();
void cancel_cb();
protected:
WordList *wordlist;
WordsEdit *wordsedit;
QPushButton *find_first,*find_next,*cancel;
QRadioButton *up,*down;
QRadioButton *start,*current;
QRadioButton *exact,*substring;
int FindLastGroup,FindLastWord;
int find_down(char *word);
int find_up(char *word);
};
//******************************************************
class ReplaceWord : public QDialog
{
Q_OBJECT
public:
ReplaceWord(string word=0,int OldGroupNum=0, int NewGroupNum=0, QWidget *parent=0, QString name=(const char*)0);
public slots:
void yes();
void yes_to_all();
void no();
void no_to_all();
};
#endif

185
src/wutil.cpp Normal file
View File

@@ -0,0 +1,185 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <stdio.h>
#include <qpainter.h>
//Added by qt3to4:
#include <Q3BoxLayout>
#include <Q3HBoxLayout>
#include <Q3VBoxLayout>
#include <QLabel>
#include <QMouseEvent>
#include <QPaintEvent>
#include "wutil.h"
QColor egacolor[16];
//**********************************************
AskNumber::AskNumber( QWidget *parent, const char *name, const char *caption,const char *prompt)
: QDialog( parent, name ,TRUE)
{
setCaption(caption);
Q3BoxLayout *all = new Q3VBoxLayout(this,20);
Q3BoxLayout *top = new Q3HBoxLayout(all,4);
QLabel *label = new QLabel(prompt,this);
top->addWidget(label);
num = new QLineEdit(this);
num->setMinimumWidth(80);
connect( num, SIGNAL(returnPressed()), SLOT(accept()) );
top->addWidget(num);
Q3BoxLayout *bottom = new Q3HBoxLayout(all,40);
QPushButton *ok = new QPushButton(this);
ok->setText("OK");
connect( ok, SIGNAL(clicked()), SLOT(accept()) );
bottom->addWidget(ok);
QPushButton *cancel = new QPushButton(this);
cancel->setText("Cancel");
connect( cancel, SIGNAL(clicked()), SLOT(reject()) );
bottom->addWidget(cancel);
}
AskText::AskText( QWidget *parent, const char *name, const char *caption,const char *prompt)
: QDialog( parent, name ,TRUE)
{
setCaption(caption);
Q3BoxLayout *all = new Q3VBoxLayout(this,20);
QLabel *label = new QLabel(prompt,this);
all->addWidget(label);
text = new QLineEdit(this);
text->setMinimumWidth(120);
connect( text, SIGNAL(returnPressed()), SLOT(accept()) );
all->addWidget(text);
Q3BoxLayout *bottom = new Q3HBoxLayout(all,40);
QPushButton *ok = new QPushButton(this);
ok->setText("OK");
connect( ok, SIGNAL(clicked()), SLOT(accept()) );
bottom->addWidget(ok);
QPushButton *cancel = new QPushButton(this);
cancel->setText("Cancel");
connect( cancel, SIGNAL(clicked()), SLOT(reject()) );
bottom->addWidget(cancel);
}
//**********************************************
void make_egacolors(void)
{
static bool ok=false;
if(ok)return;
egacolor[0]= QColor(0,0,0); //black
egacolor[1]= QColor(0,0,0xa0); //blue
egacolor[2]= QColor(0,0xa0,0); //green
egacolor[3]= QColor(0,0xa0,0xa0); //cyan
egacolor[4]= QColor(0xa0,0,0); //red
egacolor[5]= QColor(0xa0,0,0xa0); //magenta
egacolor[6]= QColor(0xa0,0x50,0); //brown
egacolor[7]= QColor(0xa0,0xa0,0xa0); //lightgray
egacolor[8]= QColor(0x50,0x50,0x50); //gray
egacolor[9]= QColor(0x50,0x50,0xff); //lightblue
egacolor[10]=QColor(0x50,0xff,0x50); //lightgreen
egacolor[11]=QColor(0x50,0xff,0xff); //lightcyan
egacolor[12]=QColor(0xff,0x50,0x50); //lightred
egacolor[13]=QColor(0xff,0x50,0xff); //lightmagenta
egacolor[14]=QColor(0xff,0xff,0x50); //yellow
egacolor[15]=QColor(0xff,0xff,0xff); //white
ok=true;
}
//*********************************************
/*******************************************************/
Palette::Palette( QWidget *parent, const char *name )
: QWidget( parent, name )
{
left=right=0;
}
void Palette::paintEvent( QPaintEvent * )
{
QPainter p (this );
int w,h,x,y,dx,dy,i;
w = this->width();
h = this->height();
dx=w/8;
dy=h/2;
w=dx*8;
h=dy*2;
for(y=0,i=0;y<h;y+=dy){
for(x=0;x<w;x+=dx,i++){
p.fillRect(x,y,dx,dy,egacolor[i]);
if(i==left){
p.setPen(i<10?egacolor[15]:egacolor[0]); //set font !
p.drawText(x+dx/4,y+dy/2,"L");
}
if(i==right){
p.setPen(i<10?egacolor[15]:egacolor[0]);
p.drawText(x+dx*2/3,y+dy/2,"R");
}
}
}
}
void Palette::mousePressEvent(QMouseEvent* event)
{
int w,h,x,y,dx,dy,i;
w = this->width();
h = this->height();
dx=w/8;
dy=h/2;
w=dx*8;
h=dy*2;
x=event->x() / dx;
y=event->y() / dy;
i=y*8+x;
if (event->button() & Qt::LeftButton){
left = i;
}
else if (event->button() & Qt::RightButton){
right = i;
}
repaint();
}

73
src/wutil.h Normal file
View File

@@ -0,0 +1,73 @@
/*
* QT AGI Studio :: Copyright (C) 2000 Helen Zommer
*
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef WUTIL_H
#define WUTIL_H
#include <qwidget.h>
#include <qlabel.h>
#include <qpushbutton.h>
#include <qlayout.h>
#include <q3listbox.h>
#include <qmessagebox.h>
#include <qlineedit.h>
#include <qradiobutton.h>
#include <q3buttongroup.h>
//Added by qt3to4:
#include <QPaintEvent>
#include <QMouseEvent>
#include <vector>
#include "global.h"
//*****************************************************
class AskNumber : public QDialog
{
Q_OBJECT
public:
AskNumber( QWidget *parent=0, const char *name=0,const char *caption=0,const char *prompt=0);
QLineEdit *num;
};
//*****************************************************
class AskText : public QDialog
{
Q_OBJECT
public:
AskText( QWidget *parent=0, const char *name=0,const char *caption=0,const char *prompt=0);
QLineEdit *text;
};
//*****************************************************
class Palette : public QWidget
{
Q_OBJECT
public:
Palette( QWidget *parent=0, const char *name=0);
void paintEvent(class QPaintEvent *);
void mousePressEvent(QMouseEvent* event);
int left,right;
};
//*****************************************************
extern QColor egacolor[];
extern void make_egacolors(void);
#endif

38
src/zoom_minus.xpm Normal file
View File

@@ -0,0 +1,38 @@
/* XPM */
static const char *zoom_minus[] = {
/* columns rows colors chars-per-pixel */
"30 30 2 1",
" c black",
". c gray100",
/* pixels */
"..............................",
"..............................",
"..............................",
"..............................",
"................. ........",
"............... ..... ......",
".............. ......... .....",
"............. ........... ....",
"............ ............. ...",
"............ ............. ...",
"........... ............... ..",
"........... ... .. ..",
"........... ... .. ..",
"........... ............... ..",
"........... ............... ..",
"............ ............. ...",
"............ ............. ...",
"............. ........... ....",
"............ ......... .....",
"........... .. ..... ......",
".......... .. ... ........",
"......... .. .................",
"........ .. ..................",
"....... .. ...................",
"...... .. ....................",
"..... .. .....................",
".... .. ......................",
"... .. .......................",
".. ........................",
".............................."
};

38
src/zoom_minus_x.xpm Normal file
View File

@@ -0,0 +1,38 @@
/* XPM */
static const char *zoom_minus_x[] = {
/* columns rows colors chars-per-pixel */
"30 30 2 1",
" c black",
". c None",
/* pixels */
"..............................",
"..............................",
"..............................",
"..............................",
"................. ........",
"............... ..... ......",
".............. ......... .....",
"............. ........... ....",
"............ ............. ...",
"............ ............. ...",
"........... ............... ..",
"........... ... .. ..",
"........... ... .. ..",
"........... ............... ..",
"........... ............... ..",
"............ ............. ...",
"............ ............. ...",
"............. ........... ....",
"............ ......... .....",
"........... .. ..... ......",
".......... .. ... ........",
"......... .. .................",
"........ .. ..................",
"....... .. ...................",
"...... .. ....................",
"..... .. .....................",
".... .. ......................",
"... .. .......................",
".. ........................",
".............................."
};

38
src/zoom_plus.xpm Normal file
View File

@@ -0,0 +1,38 @@
/* XPM */
static const char *zoom_plus[] = {
/* columns rows colors chars-per-pixel */
"30 30 2 1",
" c black",
". c gray100",
/* pixels */
"..............................",
"..............................",
"..............................",
"..............................",
"................. ........",
"............... ..... ......",
".............. ......... .....",
"............. ..... .... ....",
"............ ...... ..... ...",
"............ ...... ..... ...",
"........... ....... ...... ..",
"........... ... .. ..",
"........... ... .. ..",
"........... ....... ...... ..",
"........... ....... ...... ..",
"............ ...... ..... ...",
"............ ...... ..... ...",
"............. ........... ....",
"............ ......... .....",
"........... .. ..... ......",
".......... .. ... ........",
"......... .. .................",
"........ .. ..................",
"....... .. ...................",
"...... .. ....................",
"..... .. .....................",
".... .. ......................",
"... .. .......................",
".. ........................",
".............................."
};

38
src/zoom_plus_x.xpm Normal file
View File

@@ -0,0 +1,38 @@
/* XPM */
static const char *zoom_plus_x[] = {
/* columns rows colors chars-per-pixel */
"30 30 2 1",
" c black",
". c None",
/* pixels */
"..............................",
"..............................",
"..............................",
"..............................",
"................. ........",
"............... ..... ......",
".............. ......... .....",
"............. ..... .... ....",
"............ ...... ..... ...",
"............ ...... ..... ...",
"........... ....... ...... ..",
"........... ... .. ..",
"........... ... .. ..",
"........... ....... ...... ..",
"........... ....... ...... ..",
"............ ...... ..... ...",
"............ ...... ..... ...",
"............. ........... ....",
"............ ......... .....",
"........... .. ..... ......",
".......... .. ... ........",
"......... .. .................",
"........ .. ..................",
"....... .. ...................",
"...... .. ....................",
"..... .. .....................",
".... .. ......................",
"... .. .......................",
".. ........................",
".............................."
};