surmap: original sources

This commit is contained in:
Alexander Guryanov
2021-01-15 10:10:58 +07:00
parent 7f760017b9
commit bb1ebbf877
19 changed files with 13562 additions and 0 deletions

751
surmap/3d_shape.cpp Normal file
View File

@@ -0,0 +1,751 @@
#include "..\global.h"
#pragma hdrstop
#include "general.h"
#include "3d_shape.h"
#include "..\common.h"
#include "..\terra\vmap.h"
#include "..\terra\world.h"
#include "..\terra\render.h"
//#define _SHAPE_
#ifdef _SURMAP_
extern int DepthShow;
#else
int DepthShow;
#endif
void S3Danalyze(void);
#define COLOR_OFFSET 128
#define COLOR_SHIFT 3
int shape_control(int code);
void load_shape(char* name,int x,int y);
void view_shape();
int shape_size;
int shape_shift;
unsigned char* upper_buffer;
unsigned char* lower_buffer;
int shape_x,shape_y;
int shape_x_avr;
int shape_y_avr;
int shape_z_avr;
int shape_offset;
double shape_scale_x = 1;
double shape_scale_y = 1;
double shape_scale_z = 1;
int catch_log;
DBM A_shape(1,-1,-1,DIAGONAL);
DBM A_shape_inv(1,-1,1,DIAGONAL);
Model shape;
int shape_control(int code)
{
if(!catch_log)
return 0;
switch(code){
case VK_ESCAPE:
catch_log = 0;
break;
case VK_SPACE:
A_shape = DBM(1,-1,-1,DIAGONAL);
A_shape_inv = DBM(1,-1,1,DIAGONAL);
if(XKey.Pressed(VK_CONTROL))
shape_scale_x = shape_scale_y = shape_scale_z = 1;
break;
case VK_RETURN:
shape.height_project();
catch_log = 0;
#ifdef _SURMAP_
S3Danalyze();
#endif
break;
}
int rotate_step;
int move_step;
int alt = XKey.Pressed(VK_CONTROL);
double scale_step;
if(XKey.Pressed(VK_SHIFT)){
move_step = 20;
rotate_step = Pi/8;
scale_step = 1.1;
}
else{
move_step = 1;
rotate_step = Pi/256;
scale_step = 1.001;
}
if(XKey.Pressed(VK_DELETE)){
A_shape = DBM(-rotate_step,Z_AXIS)*A_shape;
A_shape_inv *= DBM(rotate_step,Z_AXIS);
}
if(XKey.Pressed(VK_NEXT)){
A_shape = DBM(rotate_step,Z_AXIS)*A_shape;
A_shape_inv *= DBM(-rotate_step,Z_AXIS);
}
if(XKey.Pressed(VK_HOME)){
A_shape = DBM(-rotate_step,X_AXIS)*A_shape;
A_shape_inv *= DBM(rotate_step,X_AXIS);
}
if(XKey.Pressed(VK_END)){
A_shape = DBM(rotate_step,X_AXIS)*A_shape;
A_shape_inv *= DBM(-rotate_step,X_AXIS);
}
if(XKey.Pressed(VK_INSERT)){
A_shape = DBM(rotate_step,Y_AXIS)*A_shape;
A_shape_inv *= DBM(-rotate_step,Y_AXIS);
}
if(XKey.Pressed(VK_PRIOR)){
A_shape = DBM(-rotate_step,Y_AXIS)*A_shape;
A_shape_inv *= DBM(rotate_step,Y_AXIS);
}
if(XKey.Pressed(VK_ADD) || XKey.Pressed(VK_OEM_PLUS)){
if(!alt){
shape_scale_x *= scale_step;
shape_scale_y *= scale_step;
}
shape_scale_z *= scale_step;
}
if(XKey.Pressed(VK_SUBTRACT) || XKey.Pressed(VK_OEM_MINUS)){
if(!alt){
shape_scale_x /= scale_step;
shape_scale_y /= scale_step;
}
shape_scale_z /= scale_step;
}
if(XKey.Pressed(VK_UP))
if(alt)
shape_scale_y *= scale_step;
else
shape.y_off -= move_step;
if(XKey.Pressed(VK_DOWN))
if(alt)
shape_scale_y /= scale_step;
else
shape.y_off += move_step;
if(XKey.Pressed(VK_LEFT))
if(alt)
shape_scale_x /= scale_step;
else
shape.x_off -= move_step;
if(XKey.Pressed(VK_RIGHT))
if(alt)
shape_scale_x *= scale_step;
else
shape.x_off += move_step;
#ifdef _SURMAP_
shape.x_off &= clip_mask_x;
shape.y_off &= clip_mask_y;
#endif
return 1;
}
void load_shape(char* name,int x,int y)
{
XStream c3d(name,XS_IN);
XBuffer buf(c3d.size());
c3d.read(buf.address(),c3d.size());
c3d.close();
shape.loadC3D(buf);
shape.x_off = x;
shape.y_off = y;
shape.z_off = 128;
catch_log = 1;
#ifdef _SHAPE_
upper_buffer = new unsigned char[1024*1024];
lower_buffer = new unsigned char[1024*1024];
#endif
}
#ifndef _SURMAP_
void prepare_shape(int mode,char* name,int new_size)
{
char* c3d_name = ALLOC(strlen(name) + 1,char);
strlwr(name);
strcpy(c3d_name,name);
strcpy(strstr(c3d_name,"asc"),"c3d");
if(mode & SHAPE_QUIT_IF_EXIST){
XStream c3d(0);
if(c3d.open(c3d_name,XS_IN)){
int version;
c3d > version;
if(version == C3D_VERSION_3){
XCon < "\nFile \"" < name < "\" has already been converted.\n";
return;
}
}
}
shape.loadASC(name);
double scale_mul = 1;
if(mode & SHAPE_SCALE)
scale_mul = new_size/(double)(mode & SHAPE_RELATIVE ? 100 : shape.rmax);
Vector offset = Vector(shape.x_off,shape.y_off,shape.z_off);
if(mode & SHAPE_LOAD_PARAMS){
XStream f(0);
if(f.open("shape.prm",XS_IN)){
Parser prm_in("shape.prm");
prm_in.search_name("scale_mul:");
scale_mul = prm_in.get_int();
prm_in.search_name("x_offset:");
offset.x = prm_in.get_int();
prm_in.search_name("y_offset:");
offset.y = prm_in.get_int();
offset.z = 0;
}
}
XStream prm_out("shape.prm",XS_OUT);
prm_out.SetDigits(8);
XCon < "\nConverting ASC to C3D: " < name < "\n";
prm_out < "\nConverting ASC to C3D: " < name < "\n";
XCon < "Faces: " <= shape.num_poly < "\n";
prm_out < "Faces: " <= shape.num_poly < "\n";
XCon < "Vertices: " <= shape.num_vert < "\n";
prm_out < "Vertices: " <= shape.num_vert < "\n";
XCon < "Original bound radius: " <= shape.rmax < "\n";
prm_out < "Original bound radius: " <= shape.rmax < "\n";
shape.set_colors(COLORS_IDS::BODY,0,0);
if(mode & SHAPE_MOVE)
shape.move(-offset);
shape.make_normals();
shape.pre_sorting();
shape.scale(scale_mul,1);
XCon < "Obtained bound radius: " <= shape.rmax < "\n";
prm_out < "Obtained bound radius: " <= shape.rmax < "\n";
prm_out < "scale_mul: " <= scale_mul < "\n";
prm_out < "x_offset: " <= offset.x < "\n";
prm_out < "y_offset: " <= offset.y < "\n";
XStream fout(c3d_name,XS_OUT);
shape.saveC3D(fout);
delete c3d_name;
}
#endif
void release_shape()
{
shape.free();
if(upper_buffer){
delete upper_buffer;
delete lower_buffer;
}
}
void view_shape()
{
if(!catch_log)
return;
#ifdef _SHAPE_
shape.height_project();
shape.draw_big();
#else
shape.draw_big();
#endif
}
void Model::draw_big()
{
int x = getDistX(x_off,ViewX);
int y = getDistY(y_off,ViewY);
if(DepthShow){
DBV R(x,y,0);
R *= A_g2s;
CentrX = round(R.x);
CentrY = round(R.y);
CentrZ = ViewZ + round(R.z);
}
else{
float co = Cos(TurnAngle);
float si = Sin(TurnAngle);
CentrX = round(x*co - y*si);
CentrY = round(x*si + y*co);
CentrZ = ViewZ;
}
A_convert = A_g2s*A_shape*DBM(shape_scale_x,0,0,
0,shape_scale_y,0,
0,0,shape_scale_z);
Refl = A_shape_inv*Light;
int direct;
Polygon** sort_poly;
double vx = -A_convert.a[6];
double vy = -A_convert.a[7];
double vz = -A_convert.a[8];
if(fabs(vz) >= fabs(vy))
if(fabs(vz) >= fabs(vx)){
sort_poly = sorted_polygons[Z_AXIS];
direct = SIGN(vz);
}
else{
sort_poly = sorted_polygons[X_AXIS];
direct = -SIGN(vx);
}
else
if(fabs(vx) > fabs(vy)){
sort_poly = sorted_polygons[X_AXIS];
direct = -SIGN(vx);
}
else{
sort_poly = sorted_polygons[Y_AXIS];
direct = -SIGN(vy);
}
for(register int i = 0;i < num_vert;i++)
vertices[i].convert_big();
for(i = 0;i < num_norm;i++)
normals[i].fast_calc_intensity();
if(direct > 0){
for(i = 0;i < num_poly;i++)
sort_poly[i] -> draw_gouraud_big();
}
else{
for(i = num_poly - 1;i >= 0;i--)
sort_poly[i] -> draw_gouraud_big();
}
}
void Vertex::convert_big()
{
turned = A_convert*DBV(x,y,z);
// int zz = CentrZ + turned.z;
// if(zz <= 0)
// zz = 1;
// xscr = (turned.x + CentrX)*focus/(zz) + ScreenCX;
// yscr = (turned.y + CentrY)*focus/(zz) + ScreenCY;
xscr = turned.x + CentrX + ScreenCX;
yscr = turned.y + CentrY + ScreenCY;
}
void Polygon::draw_gouraud_big()
{
#ifdef COMPACT_3D
const num_vert = 3;
#endif
#define NEXT_LEFT(p) ((p) == beg ? end : (p) - 1)
#define NEXT_RIGHT(p) ((p) == end ? beg : (p) + 1)
int xl,xr,al,ar,bl,br,d,where,Y;
int cl,cr,ckl,ckr;
int cf,cfk;
int x1,x2,len;
Vertex *lfv,*rfv,*ltv,*rtv;
Vertex **lto,**rto;
Vertex **beg,**curr,**up,**end;
Normal *lfn,*rfn,*ltn,*rtn;
unsigned char* vp;
beg = up = curr = vertices;
end = vertices + num_vert - 1;
curr++;
int t;
int x_left = (*beg) -> xscr;
int x_right = x_left;
int y_up = (*beg) -> yscr;
int y_down = y_up;
for(;curr <= end;curr++){
if(y_up > (t = (*curr) -> yscr)){
up = curr;
y_up = t;
}
if(y_down < t)
y_down = t;
if(x_left > (t = (*curr) -> xscr))
x_left = t;
if(x_right < t)
x_right = t;
}
if(y_down < VcutUp || y_up > VcutDown ||
x_right < UcutLeft || x_left > UcutRight)
return;
rfv = lfv = *up;
rfn = lfn = normals[up - beg];
lto = NEXT_LEFT(up);
ltv = *lto;
ltn = normals[lto - beg];
rto = NEXT_RIGHT(up);
rtv = *rto;
rtn = normals[rto - beg];
Y = lfv -> yscr; xl = lfv -> xscr;
al = ltv -> xscr - xl; bl = ltv -> yscr - Y;
ar = rtv -> xscr - xl; br = rtv -> yscr - Y;
xr = xl = (xl << 16) + (1 << 15);
cl = lfn -> I_8;
ckl = ltn -> I_8 - cl;
ckr = rtn -> I_8 - cl;
cr = cl <<= 7;
if(bl){
DIV16(al,bl);
ckl = (ckl << 7)/bl;
}
else
al <<= 16;
if(br){
DIV16(ar,br);
ckr = (ckr << 7)/br;
}
else
ar <<= 16;
vp = XGR_VIDEOBUF + Y*XGR_MAXX;
while(1){
if(bl > br){
d = br;
where = 0;
}
else{
d = bl;
where = 1;
}
while(d-- > 0){
x1 = xl >> 16;
x2 = xr >> 16;
if(x1 > x2)
return;
if(x1 < x2){
if(Y >= VcutUp && Y < VcutDown &&
x2 >= UcutLeft && x1 < UcutRight){
len = x2 - x1;
cf = cl;
cfk = (cr - cl)/len;
if(x1 < UcutLeft){
cf += cfk*(UcutLeft - x1);
x1 = UcutLeft;
len = x2 - x1;
}
if(x2 >= UcutRight){
x2 = UcutRight;
len = x2 - x1;
}
vp += x1;
while(len--){
*(vp++) = COLOR_OFFSET + (cf >> COLOR_SHIFT + 7);
cf += cfk;
}
vp -= x2;
}
}
Y++;
vp += XGR_MAXX;
xl += al;
xr += ar;
cl += ckl;
cr += ckr;
}
if(where){
if(ltv == rtv) return;
lfv = ltv;
lfn = ltn;
lto = NEXT_LEFT(lto);
ltv = *lto;
ltn = normals[lto - beg];
br -= bl;
xl = lfv -> xscr;
al = ltv -> xscr - xl;
bl = ltv -> yscr - Y;
xl = (xl << 16) + (1 << 15);
cl = lfn -> I_8;
ckl = ltn -> I_8 - cl;
cl <<= 7;
if(bl){
DIV16(al,bl);
ckl = (ckl << 7)/bl;
}
else{
al <<= 16;
}
}
else {
if(rtv == ltv) return;
rfv = rtv;
rfn = rtn;
rto = NEXT_RIGHT(rto);
rtv = *rto;
rtn = normals[rto - beg];
bl -= br;
xr = rfv -> xscr;
ar = rtv -> xscr - xr;
br = rtv -> yscr - Y;
xr = (xr << 16) + (1 << 15);
cr = rfn -> I_8;
ckr = rtn -> I_8 - cr;
cr <<= 7;
if(br){
DIV16(ar,br);
ckr = (ckr << 7)/br;
}
else
ar <<= 16;
}
}
}
/*******************************************************************************
Height projection
*******************************************************************************/
void Model::height_project()
{
int x,x_min = INT_INF,x_max = -INT_INF;
int y,y_min = INT_INF,y_max = -INT_INF;
int z,z_min = INT_INF,z_max = -INT_INF;
A_convert = A_shape*DBM(shape_scale_x,0,0,
0,shape_scale_y,0,
0,0,shape_scale_z);
for(int i = 0;i < num_vert;i++){
vertices[i].turned = A_convert*DBV(vertices[i].x,vertices[i].y,vertices[i].z);
if((x = vertices[i].turned.x) < x_min)
x_min = x;
if((x = vertices[i].turned.x) > x_max)
x_max = x;
if((y = vertices[i].turned.y) < y_min)
y_min = y;
if((y = vertices[i].turned.y) > y_max)
y_max = y;
if((z = -vertices[i].turned.z) < z_min)
z_min = z;
if((z = vertices[i].turned.z) > z_max)
z_max = z;
}
shape_offset = max(x_max - x_min,y_max - y_min)/2 + 2;
shape_size = max(x_max - x_min,y_max - y_min) + 2;
shape_shift = BitSR(shape_size) + 1;
shape_x = x_off + x_min - 1;
shape_y = y_off + y_min;
shape_x_avr = (x_max - x_min)/2;
shape_y_avr = (y_max - y_min)/2;
shape_z_avr = (z_max - z_min)/2 + 1;
#ifndef _SHAPE_
upper_buffer = new unsigned char[shape_size << shape_shift];
lower_buffer = new unsigned char[shape_size << shape_shift];
#endif
memset(upper_buffer,0,shape_size << shape_shift);
memset(lower_buffer,255,shape_size << shape_shift);
for(i = 0;i < num_vert;i++){
vertices[i].xscr = vertices[i].turned.x - x_min;
vertices[i].yscr = vertices[i].turned.y - y_min;
vertices[i].turned.z = -vertices[i].turned.z - z_min + 1;
}
for(i = 0;i < num_poly;i++)
polygons[i].height_project();
#ifdef _SHAPE_
c_putspr(shape_x,shape_y,1 << shape_shift,shape_size,upper_buffer,BLACK_FON);
// c_putspr(shape_x,shape_y - shape_size/2 - 2,1 << shape_shift,shape_size,upper_buffer,BLACK_FON);
// c_putspr(shape_x,shape_y + shape_size/2 + 2,1 << shape_shift,shape_size,lower_buffer,BLACK_FON);
#endif
}
void Polygon::height_project()
{
#ifdef COMPACT_3D
const num_vert = 3;
#endif
#define NEXT_LEFT(p) ((p) == beg ? end : (p) - 1)
#define NEXT_RIGHT(p) ((p) == end ? beg : (p) + 1)
int xl,xr,al,ar,bl,br,d,where,Y;
int cl,cr,ckl,ckr;
int cf,cfk,z;
int x1,x2,len,swap_log;
Vertex *lfv,*rfv,*ltv,*rtv;
Vertex **lto,**rto;
Vertex **beg,**curr,**up,**end;
unsigned char *up_vp;
unsigned char *lo_vp;
beg = up = curr = vertices;
end = vertices + num_vert - 1;
curr++;
for(;curr <= end;curr++)
if((*up) -> yscr > (*curr) -> yscr)
up = curr;
rfv = lfv = *up;
lto = NEXT_LEFT(up);
ltv = *lto;
rto = NEXT_RIGHT(up);
rtv = *rto;
Y = lfv -> yscr; xl = lfv -> xscr;
al = ltv -> xscr - xl; bl = ltv -> yscr - Y;
ar = rtv -> xscr - xl; br = rtv -> yscr - Y;
xr = xl = (xl << 16) + (1 << 15);
cl = lfv -> turned.z;
ckl = ltv -> turned.z - cl;
ckr = rtv -> turned.z - cl;
cr = cl <<= 16;
if(bl){
DIV16(al,bl);
DIV16(ckl,bl);
}
if(br){
DIV16(ar,br);
DIV16(ckr,br);
}
up_vp = upper_buffer + (Y << shape_shift);
lo_vp = lower_buffer + (Y << shape_shift);
while(1){
if(bl > br){
d = br;
where = 0;
}
else{
d = bl;
where = 1;
}
while(d-- > 0){
x1 = xl >> 16;
x2 = xr >> 16;
if(x1 != x2){
if(x1 > x2){
SWAP(x1,x2);
SWAP(cl,cr);
swap_log = 1;
}
else
swap_log = 0;
len = x2 - x1;
cf = cl;
cfk = (cr - cl)/len;
up_vp += x1;
lo_vp += x1;
while(len--){
z = cf >> 16;
if(z > 0 && z < 256){
if(*up_vp < z)
*up_vp = z;
if(*lo_vp > z)
*lo_vp = z;
}
#ifdef _FOUT_
else
fout < "High project: Over/under-flow: " <= z < "\n";
#endif
cf += cfk;
up_vp++;
lo_vp++;
}
up_vp -= x2;
lo_vp -= x2;
if(swap_log)
SWAP(cl,cr);
}
Y++;
up_vp += 1 << shape_shift;
lo_vp += 1 << shape_shift;
xl += al;
xr += ar;
cl += ckl;
cr += ckr;
}
if(where){
if(ltv == rtv) return;
lfv = ltv;
lto = NEXT_LEFT(lto);
ltv = *lto;
br -= bl;
xl = lfv -> xscr;
al = ltv -> xscr - xl;
bl = ltv -> yscr - Y;
xl = (xl << 16) + (1 << 15);
cl = lfv -> turned.z;
ckl = ltv -> turned.z - cl;
cl <<= 16;
if(bl){
DIV16(al,bl);
DIV16(ckl,bl);
}
}
else {
if(rtv == ltv) return;
rfv = rtv;
rto = NEXT_RIGHT(rto);
rtv = *rto;
bl -= br;
xr = rfv -> xscr;
ar = rtv -> xscr - xr;
br = rtv -> yscr - Y;
xr = (xr << 16) + (1 << 15);
cr = rfv -> turned.z;
ckr = rtv -> turned.z - cr;
cr <<= 16;
if(br){
DIV16(ar,br);
DIV16(ckr,br);
}
}
}
}

26
surmap/3d_shape.h Normal file
View File

@@ -0,0 +1,26 @@
// 3D Shape Interface
#define SHAPE_CONVERT 1
#define SHAPE_SCALE 2
#define SHAPE_RELATIVE 4
#define SHAPE_MOVE 8
#define SHAPE_LOAD_PARAMS 16
#define SHAPE_QUIT_IF_EXIST 32
int shape_control(int code);
void load_shape(char* name,int x,int y);
void prepare_shape(int mode,char* name,int new_size);
void release_shape();
void view_shape();
extern int shape_size;
extern int shape_shift;
extern unsigned char* upper_buffer;
extern unsigned char* lower_buffer;
extern int shape_x,shape_y;
extern int shape_x_avr;
extern int shape_y_avr;
extern int shape_z_avr;

348
surmap/dsidernd.cpp Normal file
View File

@@ -0,0 +1,348 @@
#include "..\global.h"
#pragma hdrstop
#include "..\common.h"
#include "..\3d\3d_math.h"
#include "..\terra\vmap.h"
#include "..\terra\world.h"
#include "..\terra\render.h"
#define MEMSET(a,b,c) memset(a,b,c)
typedef unsigned char BYTE;
const int POSPOWER = 8;
const int POSVAL = 1 << POSPOWER;
const int SHADOWHEIGHT = 32;
extern BYTE* shadowParent;
extern BYTE FloodLEVEL;
inline void downPreStage(int& LastStep,int HiX,BYTE* pa0,int& hC,BYTE* pmask)
{
int MaskShift = LastStep >> POSPOWER;
int x = XCYCL(HiX + 1);
BYTE* pa = pa0 + x;
BYTE* pf = pa + H_SIZE;
while(hC - MaskShift < MAX_ALT){
if(!x){
pa = pa0;
pf = pa + H_SIZE;
}
if(*pf & DOUBLE_LEVEL){
const int dh = *pa + MaskShift;
LastStep -= SHADOWDEEP;
MaskShift = LastStep >> POSPOWER;
pa++;
const int h = *pa + MaskShift;
if(hC < dh){
MEMSET(pmask + hC,1,dh - hC);
hC = dh;
}
// MEMSET(pmask + h - SS_WIDTH,1,SS_WIDTH + 1);
pa++;
}
else {
int h = *pa + MaskShift;
if(hC < h){
MEMSET(pmask + hC,1,h - hC);
hC = h;
}
LastStep -= SHADOWDEEP;
MaskShift = LastStep >> POSPOWER;
pa++;
h = *pa + MaskShift;
if(hC < h){
MEMSET(pmask + hC,1,h - hC);
hC = h;
}
pa++;
}
LastStep -= SHADOWDEEP;
MaskShift = LastStep >> POSPOWER;
x = XCYCL(x + 2);
pf += 2;
}
hC -= MAX_ALT;
}
inline void downMainStage(BYTE* pa0,int& hC,BYTE* pc0,int SizeX,int& x,BYTE*& grid,int& MaxAlt)
{
BYTE* pa = pa0 + x;
BYTE* pf = pa + H_SIZE;
BYTE* pc = pc0 + x;
BYTE* palCLRlast;
BYTE* lightCLRlast;
BYTE typeC = 0xFF;
register int i;
for(i = 0;i < SizeX;i += 2){
if(*pf & DOUBLE_LEVEL){
pa--; pf--; pc--;
const BYTE lxVal = *pa;
const BYTE rxVal = *(pa0 + XCYCL(x + 1));
const BYTE h = *pa;
const BYTE dh = *pa;
const BYTE type = (*pf & TERRAIN_MASK) >> TERRAIN_OFFSET;
const BYTE level = type ? h : FloodLEVEL;
if(type != typeC){
typeC = type;
palCLRlast = palCLR[type];
lightCLRlast = lightCLR[type];
}
grid += 3;
hC -= 3;
MaxAlt -= 3;
if(*(grid + level)){
*pf |= SHADOW_MASK;
*(pf - 1) |= SHADOW_MASK;
*(pc - 1) = *pc = palCLRlast[256 + (lightCLRlast[255 - (lxVal - rxVal)] - (255 - h >> H_CORRECTION) >> 1)];
}
else {
*pf &= ~SHADOW_MASK;
*(pf - 1) &= ~SHADOW_MASK;
*(pc - 1) = *pc = palCLRlast[256 + lightCLRlast[255 - (lxVal - rxVal)] - (255 - h >> H_CORRECTION)];
}
if(dh > hC){
MEMSET(grid + hC,1,dh - hC);
hC = dh;
}
if(h > MaxAlt) MaxAlt = h;
}
else {
BYTE lxVal = *(pa - 1);
BYTE rxVal = *(pa0 + XCYCL(x + 1));
BYTE h = *pa;
BYTE type = (*pf & TERRAIN_MASK) >> TERRAIN_OFFSET;
BYTE level = type ? h : FloodLEVEL;
grid += 1;
hC -= 1;
MaxAlt -= 1;
if(type != typeC){
typeC = type;
palCLRlast = palCLR[type];
lightCLRlast = lightCLR[type];
}
if(*(grid + level)){
*pf |= SHADOW_MASK;
*pc = palCLRlast[256 + (lightCLRlast[255 - (lxVal - rxVal)] - (255 - h >> H_CORRECTION) >> 1)];
}
else {
*pf &= ~SHADOW_MASK;
*pc = palCLRlast[256 + lightCLRlast[255 - (lxVal - rxVal)] - (255 - h >> H_CORRECTION)];
}
if(h > hC){
MEMSET(grid + hC,1,h - hC);
hC = h;
}
if(h > MaxAlt) MaxAlt = h;
pa--; pf--; pc--;
rxVal = h;
h = lxVal;
lxVal = *(pa0 + XCYCL(x - 2));
grid += 2;
hC -= 2;
MaxAlt -= 2;
type = (*pf & TERRAIN_MASK) >> TERRAIN_OFFSET;
level = type ? h : FloodLEVEL;
if(type != typeC){
typeC = type;
palCLRlast = palCLR[type];
lightCLRlast = lightCLR[type];
}
if(*(grid + level)){
*pf |= SHADOW_MASK;
*pc = palCLRlast[256 + (lightCLRlast[255 - (lxVal - rxVal)] - (255 - h >> H_CORRECTION) >> 1)];
}
else {
*pf &= ~SHADOW_MASK;
*pc = palCLRlast[256 + lightCLRlast[255 - (lxVal - rxVal)] - (255 - h >> H_CORRECTION)];
}
if(h > hC){
MEMSET(grid + hC,1,h - hC);
hC = h;
}
if(h > MaxAlt)
MaxAlt = h;
}
if(x == 1){
x = H_SIZE - 1;
pa = pa0 + x;
pf = pa + H_SIZE;
pc = pc0 + x;
}
else {
x -= 2;
pa--; pf--; pc--;
}
}
}
void regDownRender(int LowX,int LowY,int HiX,int HiY,int changed)
{
LowX = XCYCL(LowX);
HiX = XCYCL(HiX);
LowY = YCYCL(LowY);
HiY = YCYCL(HiY);
LowX &= ~1;
HiX |= 1;
int SizeY = (LowY == HiY) ? V_SIZE : YCYCL(HiY - LowY);
int SizeX = (0 == XCYCL(HiX - LowX)) ? H_SIZE : XCYCL(HiX - LowX);
int BackScanLen = 0;
register int j;
for(j = 0;j < SizeY;j++){
const int y = YCYCL(j + LowY);
BYTE* pa0 = vMap -> lineT[y];
BYTE* pc0 = vMap -> lineTcolor[y];
if(!pa0) return;
if(changed) vMap -> changedT[y] = 1;
MEMSET(shadowParent + MAX_ALT,0,(((SizeX*SHADOWDEEP) >> POSPOWER) + 2*MAX_ALT));
int hC = MAX_ALT;
int LastStep = (H_SIZE - 1 - HiX) * SHADOWDEEP;
LastStep -= ((LastStep >> POSPOWER) - MAX_ALT) << POSPOWER;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
downPreStage(LastStep,HiX,pa0,hC,shadowParent);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int x = HiX;
BYTE* grid = shadowParent + MAX_ALT;
int MaxAlt = 0;
downMainStage(pa0,hC,pc0,SizeX,x,grid,MaxAlt);
//<2F><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
x |= 1;
BYTE* pa = pa0 + x;
BYTE* pf = pa + H_SIZE;
BYTE* pc = pc0 + x;
BYTE* palCLRlast;
BYTE* lightCLRlast;
BYTE typeC = 0xFF;
int MaxPossibleAlt = MAX_ALT;
unsigned bNeedScan = 1;
while(bNeedScan && MaxPossibleAlt >= 0){
bNeedScan = 0;
if(*pf & DOUBLE_LEVEL){
pa--; pf--; pc--;
const BYTE lxVal = *pa;
const BYTE rxVal = *(pa0 + XCYCL(x + 1));
const BYTE h = *pa;
const BYTE dh = *pa;
const BYTE type = (*pf & TERRAIN_MASK) >> TERRAIN_OFFSET;
const BYTE level = type ? h : FloodLEVEL;
if(type != typeC){
typeC = type;
palCLRlast = palCLR[type];
lightCLRlast = lightCLR[type];
}
grid += 3;
hC -= 3;
MaxAlt -= 3;
MaxPossibleAlt -= 3;
if(dh < MaxAlt || (*pf & SHADOW_MASK)) bNeedScan = 1;
if(*(grid + level)){
*pf |= SHADOW_MASK;
*(pf - 1) |= SHADOW_MASK;
*(pc - 1) = *pc = palCLRlast[256 + (lightCLRlast[255 - (lxVal - rxVal)] - (255 - h >> H_CORRECTION) >> 1)];
}
else {
*pf &= ~SHADOW_MASK;
*(pf - 1) &= ~SHADOW_MASK;
*(pc - 1) = *pc = palCLRlast[256 + lightCLRlast[255 - (lxVal - rxVal)] - (255 - h >> H_CORRECTION)];
}
if(*pf & SHADOW_MASK) bNeedScan = 1;
if(dh > hC){
MEMSET(grid + hC,1,dh - hC);
hC = dh;
}
}
else {
BYTE lxVal = *(pa - 1);
BYTE rxVal = *(pa0 + XCYCL(x + 1));
BYTE h = *pa;
BYTE type = (*pf & TERRAIN_MASK) >> TERRAIN_OFFSET;
BYTE level = type ? h : FloodLEVEL;
grid += 1;
hC -= 1;
MaxAlt -= 1;
MaxPossibleAlt -= 1;
if(type != typeC){
typeC = type;
palCLRlast = palCLR[type];
lightCLRlast = lightCLR[type];
}
if(h <= MaxAlt || (*pf & SHADOW_MASK)) bNeedScan = 1;
if(*(grid + level)){
*pf |= SHADOW_MASK;
*pc = palCLRlast[256 + (lightCLRlast[255 - (lxVal - rxVal)] - (255 - h >> H_CORRECTION) >> 1)];
}
else {
*pf &= ~SHADOW_MASK;
*pc = palCLRlast[256 + lightCLRlast[255 - (lxVal - rxVal)] - (255 - h >> H_CORRECTION)];
}
if(h > hC){
MEMSET(grid + hC,1,h - hC);
hC = h;
}
pa--; pf--; pc--;
rxVal = h;
h = lxVal;
lxVal = *(pa0 + XCYCL(x - 2));
grid += 2;
hC -= 2;
MaxAlt -= 2;
MaxPossibleAlt -= 2;
type = (*pf & TERRAIN_MASK) >> TERRAIN_OFFSET;
level = type ? h : FloodLEVEL;
if(type != typeC){
typeC = type;
palCLRlast = palCLR[type];
lightCLRlast = lightCLR[type];
}
if(h <= MaxAlt || (*pf & SHADOW_MASK)) bNeedScan = 1;
if(*(grid + level)){
*pf |= SHADOW_MASK;
*pc = palCLRlast[256 + (lightCLRlast[255 - (lxVal - rxVal)] - (255 - h >> H_CORRECTION) >> 1)];
}
else {
*pf &= (~SHADOW_MASK);
*pc = palCLRlast[256 + lightCLRlast[255 - (lxVal - rxVal)] - (255 - h >> H_CORRECTION)];
}
if(h > hC){
MEMSET(grid + hC,1,h - hC);
hC = h;
}
}
if(x == 1){
x = H_SIZE - 1;
pa = pa0 + x;
pf = pa + H_SIZE;
pc = pc0 + x;
}
else {
x = XCYCL(x - 2);
pa--; pf--; pc--;
}
}
const int CurrScanLenght = XCYCL(LowX - x);
if(CurrScanLenght > BackScanLen) BackScanLen = CurrScanLenght;
}
}
}

281
surmap/impass.cpp Normal file
View File

@@ -0,0 +1,281 @@
#include "..\global.h"
#pragma hdrstop
#include "..\common.h"
#include "..\3d\3d_math.h"
#include "..\terra\vmap.h"
#include "impass.h"
#include "..\terra\world.h"
#include "..\terra\render.h"
/* ----------------------------- EXTERN SECTION ---------------------------- */
/* --------------------------- PROTOTYPE SECTION --------------------------- */
/* --------------------------- DEFINITION SECTION -------------------------- */
const int PEAK_SIZE = 9;
static uchar PeakData[PEAK_SIZE*PEAK_SIZE] = {
10, 20, 50, 80, 80, 80, 50, 20, 10,
20, 50, 80,100,100,100, 80, 50, 20,
20, 50,100,200,200,200,100, 50, 20,
20, 50,200,200,255,200,200, 50, 20,
20, 50,200,255,255,255,200, 50, 20,
20, 50,200,200,255,200,200, 50, 20,
20, 50,100,200,200,200,100, 50, 20,
20, 50, 80,100,100,100, 80, 50, 20,
10, 20, 50, 80, 80, 80, 50, 20, 10
};
ImpassType* ImpPattern[IMP_MAX];
#ifdef _SURMAP_
int curImpIndex;
char* ImpItem[IMP_MAX] = {
"SPHERE",
"POLYGON",
"PEAK"
};
#endif
void ImpassPrepare(void)
{
#ifdef _SURMAP_
XStream ff(0);
if(!ff.open("impass.dat",XS_IN)){
(ImpPattern[IMP_SPHERE] = new ImpSphere(100,100)) -> init();
(ImpPattern[IMP_POLYGON] = new ImpPolygon(100,100)) -> init();
(ImpPattern[IMP_PEAK] = new ImpPeak(PEAK_SIZE,PEAK_SIZE)) -> init();
}
else {
ImpPattern[IMP_SPHERE] = new ImpSphere(100,100);
ImpPattern[IMP_POLYGON] = new ImpPolygon(100,100);
ImpPattern[IMP_PEAK] = new ImpPeak(PEAK_SIZE,PEAK_SIZE);
ff > curImpIndex;
ImpPattern[IMP_SPHERE] -> read(ff);
ImpPattern[IMP_POLYGON] -> read(ff);
ImpPattern[IMP_PEAK] -> read(ff);
ImpPattern[IMP_SPHERE] -> init();
ImpPattern[IMP_POLYGON] -> init();
ImpPattern[IMP_PEAK] -> init();
ff.close();
}
#else
(ImpPattern[IMP_SPHERE] = new ImpSphere(10,10,0,0,0,100,5)) -> init();
// (ImpPattern[IMP_POLYGON] = new ImpPolygon(50,50,0,0,0,100,100)) -> init();
// (ImpPattern[IMP_PEAK] = new ImpPeak(PEAK_SIZE,PEAK_SIZE,0,0,0,100,100)) -> init();
#endif
}
void ImpassSave(void)
{
#ifdef _SURMAP_
XStream ff("impass.dat",XS_OUT);
ff < curImpIndex;
ImpPattern[IMP_SPHERE] -> write(ff);
ImpPattern[IMP_POLYGON] -> write(ff);
ImpPattern[IMP_PEAK] -> write(ff);
ff.close();
#endif
}
ImpassType::ImpassType(int _sx,int _sy,int _force,int _mode,int _level,int _rad,int _h,int _n,int _phase,int _inverse,int _plain,int _noiseLevel,int _noiseAmp)
{
map = NULL;
sx = _sx; sy = _sy;
level = _level;
mode = _mode;
force = _force;
radInt = _rad;
rad = (double)_rad/100.;
h = _h;
n = _n;
phase = _phase;
inverse = _inverse;
plain = _plain;
noiseLevel = _noiseLevel;
noiseAmp = _noiseAmp;
}
void ImpassType::init(void)
{
map = NULL;
change(sx,sy,force,mode,level,radInt,h,n,phase,inverse,plain,noiseLevel,noiseAmp);
}
void ImpassType::read(XStream& ff)
{
ff > sx > sy > level > force > mode > radInt > h > n > phase > inverse > plain > noiseLevel > noiseAmp;
}
void ImpassType::write(XStream& ff)
{
ff < sx < sy < level < force < mode < radInt < h < n < phase < inverse < plain < noiseLevel < noiseAmp;
}
void ImpassType::change(int _sx,int _sy,int _force,int _mode,int _level,int _rad,int _h,int _n,int _phase,int _inverse,int _plain,int _noiseLevel,int _noiseAmp)
{
if(!_sx) _sx = 16; if(!_sy) _sy = 16;
sx = _sx; sy = _sy;
size = sx*sy;
level = _level;
mode = _mode;
force = _force;
radInt = _rad;
rad = (double)_rad/100.;
h = _h;
n = _n;
phase = _phase;
inverse = _inverse;
plain = _plain;
noiseLevel = _noiseLevel;
noiseAmp = _noiseAmp;
if(map) delete map;
map = new short[size];
register int i;
short* p = map;
for(i = 0;i < size;i++,p++) *p = level;
build();
ImpassSave();
}
#ifdef _SURMAP_
void ImpassType::put(int x,int y)
{
x -= sx/2;
y -= sy/2;
register int i,j;
int xx,yy,v,vv = 0;
short* p = map;
uchar** lt = vMap -> lineT;
vMap -> increase(y,y + sy - 1);
for(j = 0;j < sy;j++)
for(i = 0;i < sx;i++,p++)
if(force || *p != level){
xx = XCYCL(x + i);
yy = YCYCL(y + j);
if(lt[yy]){
v = *(lt[yy] + xx);
switch(mode){
case 0:
vv = *p;
break;
case 1:
vv = MAX(v,*p);
if(vv != *p) continue;
break;
case 2:
vv = MIN(v,*p);
if(vv != *p) continue;
break;
case 3:
vv = v + *p >> 1;
break;
case 4:
vv = v + *p;
break;
}
if(noiseLevel && noiseAmp)
if((int)realRND(100) < noiseLevel) vv += noiseAmp - realRND((noiseAmp << 1) + 1);
pixSet(xx,yy,vv - v);
}
}
regRender(x,y,x + sx,y + sy);
}
#endif
static double plane(double x,double y, double x0,double y0,double z0,double x1,double y1,double z1,double x2,double y2,double z2)
{
double a = (y1 - y0)*(z2 - z0) - (z1 - z0)*(y2 - y0);
double b = (x1 - x0)*(z2 - z0) - (z1 - z0)*(x2 - x0);
double c = (x1 - x0)*(y2 - y0) - (y1 - y0)*(x2 - x0);
return ((y - y0)*b - (x - x0)*a)/c + z0;
}
static double minim(double* d,int n)
{
double m = 1000.0;
for(int i = 0;i < n;i++)
if(d[i] >= 0 && d[i] < m) m = d[i];
return m;
}
ImpSphere::ImpSphere(int _sx,int _sy,int _force,int _mode,int _level,int _rad,int _h,int _n,int _phase,int _inverse,int _plain,int _noiseLevel,int _noiseAmp)
: ImpassType(_sx,_sy,_force,_mode,_level,_rad,_h,_n,_phase,_inverse,_plain,_noiseLevel,_noiseAmp)
{ }
void ImpSphere::build(void)
{
double dx = 2.0/(double)sx;
double dy = 2.0/(double)sy;
double xx,yy,zz;
double r2 = rad*rad;
register int x,y;
short* p = map;
for(yy = -1.0,y = 0;y < sy;yy += dy,y++)
for(xx = -1.0,x = 0;x < sx;xx += dx,x++,p++){
zz = r2 - (xx*xx + yy*yy);
if(zz > 0.0){
*p = (short)(sqrt(zz)*h);
if(inverse) *p = -*p;
if(plain) *p = level;
else *p += level;
}
}
}
ImpPolygon::ImpPolygon(int _sx,int _sy,int _force,int _mode,int _level,int _rad,int _h,int _n,int _phase,int _inverse,int _plain,int _noiseLevel,int _noiseAmp)
: ImpassType(_sx,_sy,_force,_mode,_level,_rad,_h,_n,_phase,_inverse,_plain,_noiseLevel,_noiseAmp)
{ }
void ImpPolygon::build(void)
{
double dx = 2.0/(double)sx;
double dy = 2.0/(double)sy;
double xx,yy,zz;
double* zzz = new double[n];
double phs = (double)phase/1000.;
double angle = 2.*M_PI/(double)n;
double ang;
register int x,y,i;
short* p = map;
for(yy = 1.0,y = 0;y < sy;yy -= dy,y++)
for(xx = -1.0,x = 0;x < sx;xx += dx,x++,p++){
// zzz[0] = plane(xx,yy, -rad,rad,0.0, rad,rad,0.0, 0.0,0.0,(double)h/256.);
// zzz[1] = plane(xx,yy, -rad,-rad,0.0, rad,-rad,0.0, 0.0,0.0,(double)h/256.);
// zzz[2] = plane(xx,yy, -rad,rad,0.0, -rad,-rad,0.0, 0.0,0.0,(double)h/256.);
// zzz[3] = plane(xx,yy, rad,rad,0.0, rad,-rad,0.0, 0.0,0.0,(double)h/256.);
for(ang = phs,i = 0;i < n;i++,ang += angle){
zzz[i] = plane(xx,yy,rad*sin(ang),rad*cos(ang),0.0, rad*sin(ang + angle),rad*cos(ang + angle),0.0, 0.0,0.0,(double)h/256.);
if(zzz[i] < 0.0) zzz[i] = 0.0;
}
zz = minim(zzz,n);
if(zz > 0){
*p = (short)(zz*h);
if(inverse) *p = -*p;
if(plain) *p = level;
else *p += level;
}
}
delete zzz;
}
ImpPeak::ImpPeak(int _sx,int _sy,int _force,int _mode,int _level,int _rad,int _h,int _n,int _phase,int _inverse,int _plain,int _noiseLevel,int _noiseAmp)
: ImpassType(_sx,_sy,_force,_mode,_level,_rad,_h)
{ }
void ImpPeak::build(void)
{
for(int i = 0;i < sx*sy;i++) map[i] = PeakData[i];
}

66
surmap/impass.h Normal file
View File

@@ -0,0 +1,66 @@
#define IMP_SPHERE 0
#define IMP_POLYGON 1
#define IMP_PEAK 2
#define IMP_MAX 3
struct ImpassType;
void ImpassPrepare(void);
void ImpassSave(void);
extern ImpassType* ImpPattern[IMP_MAX];
#ifdef _SURMAP_
extern int curImpIndex;
extern char* ImpItem[IMP_MAX];
#endif
struct ImpassType {
int sx,sy,size;
int level;
int force;
int mode;
int radInt;
int h;
int n,phase;
int inverse;
int plain;
int noiseLevel,noiseAmp;
double rad;
short* map;
ImpassType(int _sx,int _sy,int _force = 0,int _mode = 0,int _level = 0,int _rad = 100,int _h = 256,int _n = 4,int _phase = 0,int _inverse = 0,int _plain = 0,int _noiseLevel = 0,int _noiseAmp = 0);
~ImpassType(void){ delete map; }
virtual void build(void){}
void put(int x,int y);
void change(int _sx,int _sy,int _force = 0,int _mode = 0,int _level = 0,int _rad = 100,int _h = 256,int _n = 4,int _phase = 0,int _inverse = 0,int _plain = 0,int _noiseLevel = 0,int _noiseAmp = 0);
void init(void);
void read(XStream& ff);
void write(XStream& ff);
};
struct ImpSphere : ImpassType {
ImpSphere(int _sx,int _sy,int _force = 0,int _mode = 0,int _level = 0,int _rad = 100,int _h = 256,int _n = 4,int _phase = 0,int _inverse = 0,int _plain = 0,int _noiseLevel = 0,int _noiseAmp = 0);
virtual void build(void);
};
struct ImpPolygon : ImpassType {
ImpPolygon(int _sx,int _sy,int _force = 0,int _mode = 0,int _level = 0,int _rad = 100,int _h = 256,int _n = 4,int _phase = 0,int _inverse = 0,int _plain = 0,int _noiseLevel = 0,int _noiseAmp = 0);
virtual void build(void);
};
struct ImpPeak : ImpassType {
ImpPeak(int _sx,int _sy,int _force = 0,int _mode = 0,int _level = 0,int _rad = 100,int _h = 256,int _n = 4,int _phase = 0,int _inverse = 0,int _plain = 0,int _noiseLevel = 0,int _noiseAmp = 0);
virtual void build(void);
};

18
surmap/runtime.h Normal file
View File

@@ -0,0 +1,18 @@
//const RTO_SURMAP_TIMER = CLOCKS_PER_SEC/20;
const int RTO_SURMAP_TIMER = 0;
// Runtime objects...
enum SurmapRuntimeObjID
{
RTO_SURMAP_ID = 1,
RTO_MAX_ID
};
struct SurmapRTO : XRuntimeObject
{
virtual int Quant(void);
SurmapRTO(void) : XRuntimeObject(RTO_SURMAP_ID){ Timer = RTO_SURMAP_TIMER; }
};

429
surmap/siderend.cpp Normal file
View File

@@ -0,0 +1,429 @@
#include "..\global.h"
#pragma hdrstop
#include "..\common.h"
#include "..\3d\3d_math.h"
#include "..\terra\vmap.h"
#include "..\terra\world.h"
#include "..\terra\render.h"
#define MEMSET(a,b,c) memset(a,b,c)
typedef unsigned char BYTE;
const int POSPOWER = 8;
const int POSVAL = 1 << POSPOWER;
const int SHADOWHEIGHT = 32;
extern BYTE* shadowParent;
extern BYTE FloodLEVEL;
extern int RenderingLayer;
void regDownRender(int LowX,int LowY,int HiX,int HiY,int changed);
inline void PreStage(int& LastStep,int HiX,BYTE* pa0,int& hC,BYTE* pmask)
{
int MaskShift = LastStep >> POSPOWER;
int x = XCYCL(HiX + 1);
BYTE* pa = pa0 + x;
BYTE* pf = pa + H_SIZE;
while(hC - MaskShift < MAX_ALT){
if(!x){
pa = pa0;
pf = pa + H_SIZE;
}
if(*pf & DOUBLE_LEVEL){
const int dh = *pa + MaskShift;
LastStep -= SHADOWDEEP;
MaskShift = LastStep >> POSPOWER;
pa++;
const int h = *pa + MaskShift;
if(hC < dh){
MEMSET(pmask + hC,1,dh - hC);
hC = dh;
}
MEMSET(pmask + h - SS_WIDTH,1,SS_WIDTH + 1);
pa++;
}
else {
int h = *pa + MaskShift;
if(hC < h){
MEMSET(pmask + hC,1,h - hC);
hC = h;
}
LastStep -= SHADOWDEEP;
MaskShift = LastStep >> POSPOWER;
pa++;
h = *pa + MaskShift;
if(hC < h){
MEMSET(pmask + hC,1,h - hC);
hC = h;
}
pa++;
}
LastStep -= SHADOWDEEP;
MaskShift = LastStep >> POSPOWER;
x = XCYCL(x + 2);
pf += 2;
}
hC -= MAX_ALT;
}
inline void MainStage(BYTE* pa0,int& hC,BYTE* pc0,int SizeX,int& x,BYTE*& grid,int& MaxAlt)
{
BYTE* pa = pa0 + x;
BYTE* pf = pa + H_SIZE;
BYTE* pc = pc0 + x;
BYTE* palCLRlast;
BYTE* lightCLRlast;
BYTE typeC = 0xFF;
register int i;
for(i = 0;i < SizeX;i += 2){
if(*pf & DOUBLE_LEVEL){
const BYTE lxVal = *pa;
const BYTE rxVal = *(pa0 + XCYCL(x + 2));
const BYTE h = *pa;
const BYTE dh = *(pa - 1);
const BYTE type = (*pf & TERRAIN_MASK) >> TERRAIN_OFFSET;
#ifndef TERRAIN16
const BYTE level = type ? h : FloodLEVEL;
#else
const BYTE level = h;
#endif
if(type != typeC){
typeC = type;
palCLRlast = palCLR[type];
lightCLRlast = lightCLR[type];
}
grid += 3;
hC -= 3;
MaxAlt -= 3;
if(*(grid + level)){
*pf |= SHADOW_MASK;
*(pf - 1) |= SHADOW_MASK;
*(pc - 1) = *pc = palCLRlast[256 + (lightCLRlast[255 - (lxVal - rxVal)] - (255 - h >> H_CORRECTION) >> 1)];
}
else {
*pf &= ~SHADOW_MASK;
*(pf - 1) &= ~SHADOW_MASK;
*(pc - 1) = *pc = palCLRlast[256 + lightCLRlast[255 - (lxVal - rxVal)] - (255 - h >> H_CORRECTION)];
}
#ifndef TERRAIN16
if(*(grid + SHADOWHEIGHT + level)){
*pf |= OBJSHADOW;
*(pf - 1) |= OBJSHADOW;
}
else {
*pf &= ~OBJSHADOW;
*(pf - 1) &= ~OBJSHADOW;
}
#endif
pa--; pf--; pc--;
if(dh > hC){
MEMSET(grid + hC,1,dh - hC);
hC = dh;
}
MEMSET(grid + h - SS_WIDTH,1,SS_WIDTH + 1);
if(h > MaxAlt) MaxAlt = h;
}
else {
BYTE lxVal = *(pa - 1);
BYTE rxVal = *(pa0 + XCYCL(x + 1));
BYTE h = *pa;
BYTE type = (*pf & TERRAIN_MASK) >> TERRAIN_OFFSET;
#ifndef TERRAIN16
BYTE level = type ? h : FloodLEVEL;
#else
BYTE level = h;
#endif
grid += 1;
hC -= 1;
MaxAlt -= 1;
if(type != typeC){
typeC = type;
palCLRlast = palCLR[type];
lightCLRlast = lightCLR[type];
}
if(*(grid + level)){
*pf |= SHADOW_MASK;
*pc = palCLRlast[256 + (lightCLRlast[255 - (lxVal - rxVal)] - (255 - h >> H_CORRECTION) >> 1)];
}
else {
*pf &= ~SHADOW_MASK;
*pc = palCLRlast[256 + lightCLRlast[255 - (lxVal - rxVal)] - (255 - h >> H_CORRECTION)];
}
#ifndef TERRAIN16
if(*(grid + SHADOWHEIGHT + level))
*pf |= OBJSHADOW;
else
*pf &= ~OBJSHADOW;
#endif
if(h > hC){
MEMSET(grid + hC,1,h - hC);
hC = h;
}
if(h > MaxAlt) MaxAlt = h;
pa--; pf--; pc--;
rxVal = h;
h = lxVal;
lxVal = *(pa0 + XCYCL(x - 2));
grid += 2;
hC -= 2;
MaxAlt -= 2;
type = (*pf & TERRAIN_MASK) >> TERRAIN_OFFSET;
#ifndef TERRAIN16
level = type ? h : FloodLEVEL;
#else
level = h;
#endif
if(type != typeC){
typeC = type;
palCLRlast = palCLR[type];
lightCLRlast = lightCLR[type];
}
if(*(grid + level)){
*pf |= SHADOW_MASK;
*pc = palCLRlast[256 + (lightCLRlast[255 - (lxVal - rxVal)] - (255 - h >> H_CORRECTION) >> 1)];
}
else {
*pf &= ~SHADOW_MASK;
*pc = palCLRlast[256 + lightCLRlast[255 - (lxVal - rxVal)] - (255 - h >> H_CORRECTION)];
}
#ifndef TERRAIN16
if(*(grid + SHADOWHEIGHT + level))
*pf |= OBJSHADOW;
else
*pf &= ~OBJSHADOW;
#endif
if(h > hC){
MEMSET(grid + hC,1,h - hC);
hC = h;
}
if(h > MaxAlt)
MaxAlt = h;
}
if(x == 1){
x = H_SIZE - 1;
pa = pa0 + x;
pf = pa + H_SIZE;
pc = pc0 + x;
}
else {
x -= 2;
pa--; pf--; pc--;
}
}
}
void regRender(int LowX,int LowY,int HiX,int HiY,int changed)
{
#ifdef _SURMAP_
if(RenderingLayer == DOWN_LAYER){
regDownRender(LowX,LowY,HiX,HiY,changed);
return;
}
#endif
LowX = XCYCL(LowX);
HiX = XCYCL(HiX);
LowY = YCYCL(LowY);
HiY = YCYCL(HiY);
LowX &= ~1;
HiX |= 1;
int SizeY = (LowY == HiY) ? V_SIZE : YCYCL(HiY - LowY);
int SizeX = (0 == XCYCL(HiX - LowX)) ? H_SIZE : XCYCL(HiX - LowX);
int BackScanLen = 0;
register int j;
for(j = 0;j < SizeY;j++){
const int y = YCYCL(j + LowY);
BYTE* pa0 = vMap -> lineT[y];
BYTE* pc0 = vMap -> lineTcolor[y];
if(!pa0) return;
if(changed) vMap -> changedT[y] = 1;
MEMSET(shadowParent,0,(((SizeX*SHADOWDEEP) >> POSPOWER) + 4*MAX_ALT));
// MEMSET(shadowParent,0,map_size_x);
int hC = MAX_ALT;
int LastStep = (H_SIZE - 1 - HiX) * SHADOWDEEP;
LastStep -= ((LastStep >> POSPOWER) - MAX_ALT) << POSPOWER;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
PreStage(LastStep,HiX,pa0,hC,shadowParent + MAX_ALT);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int x = HiX;
BYTE* grid = shadowParent + MAX_ALT + MAX_ALT;
int MaxAlt = 0;
MainStage(pa0,hC,pc0,SizeX,x,grid,MaxAlt);
//<2F><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
x |= 1;
BYTE* pa = pa0 + x;
BYTE* pf = pa + H_SIZE;
BYTE* pc = pc0 + x;
BYTE* palCLRlast;
BYTE* lightCLRlast;
BYTE typeC = 0xFF;
int MaxPossibleAlt = MAX_ALT;
unsigned bNeedScan = 1;
while(bNeedScan && MaxPossibleAlt >= 0){
bNeedScan = 0;
if(*pf & DOUBLE_LEVEL){
const BYTE lxVal = *pa;
const BYTE rxVal = *(pa0 + XCYCL(x + 2));
const BYTE h = *pa;
const BYTE dh = *(pa - 1);
const BYTE type = (*pf & TERRAIN_MASK) >> TERRAIN_OFFSET;
#ifndef TERRAIN16
const BYTE level = type ? h : FloodLEVEL;
#else
const BYTE level = h;
#endif
if(type != typeC){
typeC = type;
palCLRlast = palCLR[type];
lightCLRlast = lightCLR[type];
}
grid += 3;
hC -= 3;
MaxAlt -= 3;
MaxPossibleAlt -= 3;
if(dh < MaxAlt || (*pf & SHADOW_MASK)) bNeedScan = 1;
if(*(grid + level)){
*pf |= SHADOW_MASK;
*(pf - 1) |= SHADOW_MASK;
*(pc - 1) = *pc = palCLRlast[256 + (lightCLRlast[255 - (lxVal - rxVal)] - (255 - h >> H_CORRECTION) >> 1)];
}
else {
*pf &= ~SHADOW_MASK;
*(pf - 1) &= ~SHADOW_MASK;
*(pc - 1) = *pc = palCLRlast[256 + lightCLRlast[255 - (lxVal - rxVal)] - (255 - h >> H_CORRECTION)];
}
#ifndef TERRAIN16
if(*(grid + SHADOWHEIGHT + level)){
*pf |= OBJSHADOW;
*(pf - 1) |= OBJSHADOW;
}
else {
*pf &= ~OBJSHADOW;
*(pf - 1) &= ~OBJSHADOW;
}
#endif
pa--; pf--; pc--;
if(*pf & SHADOW_MASK) bNeedScan = 1;
if(dh > hC){
MEMSET(grid + hC,1,dh - hC);
hC = dh;
}
MEMSET(grid + h - SS_WIDTH,1,SS_WIDTH + 1);
}
else {
BYTE lxVal = *(pa - 1);
BYTE rxVal = *(pa0 + XCYCL(x + 1));
BYTE h = *pa;
BYTE type = (*pf & TERRAIN_MASK) >> TERRAIN_OFFSET;
#ifndef TERRAIN16
BYTE level = type ? h : FloodLEVEL;
#else
BYTE level = h;
#endif
grid += 1;
hC -= 1;
MaxAlt -= 1;
MaxPossibleAlt -= 1;
if(type != typeC){
typeC = type;
palCLRlast = palCLR[type];
lightCLRlast = lightCLR[type];
}
if(h <= MaxAlt || (*pf & SHADOW_MASK)) bNeedScan = 1;
if(*(grid + level)){
*pf |= SHADOW_MASK;
*pc = palCLRlast[256 + (lightCLRlast[255 - (lxVal - rxVal)] - (255 - h >> H_CORRECTION) >> 1)];
}
else {
*pf &= ~SHADOW_MASK;
*pc = palCLRlast[256 + lightCLRlast[255 - (lxVal - rxVal)] - (255 - h >> H_CORRECTION)];
}
#ifndef TERRAIN16
if(*(grid + SHADOWHEIGHT + level))
*pf |= OBJSHADOW;
else
*pf &= ~OBJSHADOW;
#endif
if(h > hC){
MEMSET(grid + hC,1,h - hC);
hC = h;
}
pa--; pf--; pc--;
rxVal = h;
h = lxVal;
lxVal = *(pa0 + XCYCL(x - 2));
grid += 2;
hC -= 2;
MaxAlt -= 2;
MaxPossibleAlt -= 2;
type = (*pf & TERRAIN_MASK) >> TERRAIN_OFFSET;
#ifndef TERRAIN16
level = type ? h : FloodLEVEL;
#else
level = h;
#endif
if(type != typeC){
typeC = type;
palCLRlast = palCLR[type];
lightCLRlast = lightCLR[type];
}
if(h <= MaxAlt || (*pf & SHADOW_MASK)) bNeedScan = 1;
if(*(grid + level)){
*pf |= SHADOW_MASK;
*pc = palCLRlast[256 + (lightCLRlast[255 - (lxVal - rxVal)] - (255 - h >> H_CORRECTION) >> 1)];
}
else {
*pf &= ~SHADOW_MASK;
*pc = palCLRlast[256 + lightCLRlast[255 - (lxVal - rxVal)] - (255 - h >> H_CORRECTION)];
}
#ifndef TERRAIN16
if(*(grid + SHADOWHEIGHT + level))
*pf |= OBJSHADOW;
else
*pf &= ~OBJSHADOW;
#endif
if(h > hC){
MEMSET(grid + hC,1,h - hC);
hC = h;
}
}
if(x == 1){
x = H_SIZE - 1;
pa = pa0 + x;
pf = pa + H_SIZE;
pc = pc0 + x;
}
else {
x = XCYCL(x - 2);
pa--; pf--; pc--;
}
}
const int CurrScanLenght = XCYCL(LowX - x);
if(CurrScanLenght > BackScanLen) BackScanLen = CurrScanLenght;
}
}
}

1630
surmap/sqexp.cpp Normal file

File diff suppressed because it is too large Load Diff

156
surmap/sqexp.h Normal file
View File

@@ -0,0 +1,156 @@
#define E_LBMREEV 23
#define E_MAINMAP 24
#define E_LAYERMENU 25
#define E_MAINMENU 26
#define E_PRMMENU 27
#define E_MUFLER 28
#define E_OPENFORM 100
#define E_SAVEFORM 101
#define E_IMPCHOICE 102
#define E_BMPCHOICE 103
#define E_IMPSPHERE 104
#define E_IMPPOLYGON 105
#define E_IMPPEAK 106
#define E_TRACKFORM 107
#define E_GOTOFORM 108
#define E_PLACEBMPFORM 109
#define E_IBMFORM 110
#define E_MOSAICFORM 111
#define E_FORM3D 112
#define E_MOBILOCMENU 113
#define E_MOBILOCFORM 114
#define E_MOBILOCSHOWCHOICE 115
#define E_MOBILOCDELETECHOICE 116
#define E_MOBILOCEDITCHOICE 117
#define E_MOBILOCCHOICE 118
#define E_WORLDCHOICE 119
#define E_VALOCMENU 120
#define E_VLTNTFORM 121
#define E_VLMLCFORM 122
#define E_VLSNSFORM 123
#define E_VLDNGFORM 124
#define E_MOBILOCFRAMECHOICE 125
#define PRM_ROTMAP 0x0001
#define PRM_INFO 0x0002
struct iGameMap : sqInputBox {
int xc,yc; // xmouse - xc + XC
int xside,yside;
int xsize,ysize;
int _xI,_yI;
int CX,CY;
int DX,DY;
int TurnAngle;
int TurnD;
int TurnSecX;
int prmFlag;
int FirstDraw;
int isreEvent,reEvent;
sqTextButton* knob3D;
sqTextButton* knobAlt;
sqTextButton* knobRender;
sqTextButton* knobTrack;
sqTextButton* knobSpline;
sqTextButton* knobBuild;
sqTextButton* knobBuildAll;
sqTextButton* knobLinking;
iGameMap(sqElem* _owner,int _x,int _y,int _xside,int _yside,char* _title);
~iGameMap(void){ }
virtual void message(int code,sqElem* object = NULL);
virtual void keytrap(int key);
virtual void draw(int self = 1);
virtual void flush(void);
virtual void quant(void);
virtual void handler(sqEvent* e);
void reset(void);
void change(int Dx,int Dy);
void gotoxy(int x,int y);
void shift(int dx,int dy){ gotoxy(CX + dx,CY + dy); }
void setFloodLvl(void);
void restoreFloodLvl(void);
};
extern iGameMap* curGMap;
struct iMainMenu : sqInputBox {
sqPopupMenu* menu;
int x0,y0;
static int copt;
iMainMenu(sqElem* _owner,int _x,int _y);
virtual void message(int code,sqElem* object = NULL);
virtual void flush(void);
};
struct iPrmMenu : sqInputBox {
sqPopupMenu* menu;
int x0,y0;
XBuffer* buf;
static int copt;
iPrmMenu(sqElem* _owner,int _x,int _y);
~iPrmMenu(void){ delete buf; }
virtual void message(int code,sqElem* object = NULL);
virtual void flush(void);
virtual void keytrap(int key);
};
struct iLayerMenu : sqInputBox {
sqPopupMenu* menu;
int x0,y0;
XBuffer* buf;
static int copt;
iLayerMenu(sqElem* _owner,int _x,int _y);
~iLayerMenu(void){ delete buf; }
virtual void message(int code,sqElem* object = NULL);
virtual void flush(void);
virtual void keytrap(int key);
};
struct iInputForm : sqInputBox {
sqField* name;
int x0,y0;
int mode;
sqField* params[256];
sqPopupMenu* menu;
static int copt;
iInputForm(sqElem* _owner,int _x,int _y,int _mode);
virtual void message(int code,sqElem* object = NULL);
virtual void flush(void);
virtual void quant(void);
};
void SetMCursor(int mode = 0);
struct ibmFile {
int mapx_center,mapy_center;
int x_center,y_center;
int x_size,y_size;
int x_side,y_side;
int level;
uchar* image;
int counter,fcnt;
int shoting;
void save(int _mapx_center,int _mapy_center,int _x_center,int _y_center,int _x_size,int _y_size,int _x_side,int _y_side,int _level,int _counter);
void quantSave(void);
};

794
surmap/sqibody.cpp Normal file
View File

@@ -0,0 +1,794 @@
/*
Simple-Quick Interface by K-Division::KranK
All Rights Reserved (C)1995
(Main Constructions)
*/
#include "..\global.h"
#pragma hdrstop
#include "sqint.h"
/* ---------------------------- EXTERN SECTION ----------------------------- */
/* --------------------------- PROTOTYPE SECTION --------------------------- */
/* --------------------------- DEFINITION SECTION -------------------------- */
int sqInputString::insert = 1,sqInputString::rus;
static char* EventMsg = "EventQueue overflow. Reboot?";
inline char* sqstrNcpy(char* dest,char* src,int len)
{
register int i = 0;
while(src[i] && i < len) { dest[i] = src[i]; i++; }
dest[i] = '\0';
return dest;
}
void sqEventQueue::put(int _code)
{
int n = (top + 1)%max;
if(n == bottom) return; //ErrH.Abort(EventMsg);
sqEvent* e = queue + top;
e -> code = _code; e -> type = E_COMMON;
top = n;
}
void sqEventQueue::put(int _code,int _type,int _x,int _y)
{
int n = (top + 1)%max;
if(n == bottom) return; //ErrH.Abort(EventMsg);
sqEvent* e = queue + top;
e -> code = _code; e -> x = _x; e -> y = _y; e -> type = _type;
top = n;
}
void sqEventQueue::put(int _code,int _type,int _x,int _y,void* _pointer,int _value)
{
int n = (top + 1)%max;
if(n == bottom) return; //ErrH.Abort(EventMsg);
sqEvent* e = queue + top;
e -> code = _code; e -> x = _x; e -> y = _y; e -> type = _type; e -> pointer = _pointer; e -> value = _value;
top = n;
}
sqEvent* sqEventQueue::get(void)
{
if(top == bottom){
return NULL;
}
sqEvent* r = queue + bottom;
bottom = (bottom + 1)%max;
return r;
}
sqElem::sqElem(int _height,int _dxl,int _dyl,int _dxr,int _dyr)
{
dxl = _dxl; dyl = _dyl;
dxr = _dxr; dyr = _dyr;
height = _height;
tail = owner = NULL;
}
int* sqElem::getXY(void){ return NULL; }
void sqElem::handler(sqEvent* e){}
void sqElem::accept(void){}
void sqElem::restore(int _x,int _y,int _sx,int _sy){}
void sqElem::keytrap(int key){}
void sqElem::message(int code,sqElem* object){}
void sqElem::activate(int force){}
void sqElem::deactivate(void){}
void sqElem::flush(void){}
void sqElem::quant(void)
{
sqElem* p = tail;
if(p)
do {
p -> quant();
p = p -> next;
} while(p != tail);
}
void sqElem::remove(void)
{
if(owner) owner -> restore(getX() + xl - height,getY() + yl,xr - xl + height + 1,yr - yl + height + 1);
}
void sqElem::draw(int self)
{
#ifdef _SELFDRAW_
if(self){
if(height >= 1){
XGR_LineTo(getX() + xl - 1,getY() + yr + 1,xr - xl + 1,2,SQ_SYSCOLOR);
XGR_LineTo(getX() + xl - 1,getY() + yl + 1,yr - yl,3,SQ_SYSCOLOR);
}
if(height >= 2){
XGR_LineTo(getX() + xl - 2,getY() + yr + 2,xr - xl + 1,2,SQ_SYSCOLOR);
XGR_LineTo(getX() + xl - 2,getY() + yl + 2,yr - yl,3,SQ_SYSCOLOR);
}
}
#endif
sqElem* p = tail;
if(p)
do {
p -> draw();
p = p -> next;
} while(p != tail);
}
int sqElem::ishere(int x,int y)
{
if(x >= getX() + xl && x <= getX() + xr && y >= getY() + yl && y <= getY() + yr) return 1;
return 0;
}
void sqElem::set(int _height)
{
int* d = getXY();
xl = d[0] + dxl; yl = d[1] + dyl;
xr = d[0] + d[2] - 1 + dxr; yr = d[1] + d[3] - 1 + dyr;
height = _height;
}
sqElem& sqElem::operator+ (sqElem* e)
{
if(tail){
e -> prev = tail -> prev;
e -> next = tail;
tail -> prev -> next = e;
tail -> prev = e;
}
else
tail = e -> prev = e -> next = e;
e -> owner = this;
e -> accept();
return *this;
}
sqElem& sqElem::operator- (sqElem* e)
{
e -> reject();
if(e == tail){
if(tail -> next != tail){
tail -> next -> prev = tail -> prev;
tail -> prev -> next = tail -> next;
tail = tail -> next;
}
else tail = NULL;
}
else {
e -> next -> prev = e -> prev;
e -> prev -> next = e -> next;
}
delete e;
return *this;
}
void sqElem::reject(void)
{
while(tail) *this - tail;
}
int sqElem::process(sqEvent* event)
{
if(event -> type == E_COMMON) handler(event);
sqElem* p = tail;
if(p)
do {
if(p -> process(event)) return 1;
p = p -> next;
} while(p != tail);
if(event -> type == E_REGION && ishere(event -> x,event -> y)){
handler(event);
return 1;
}
return 0;
}
void sqBox::draw(int self)
{
#ifdef _SELFDRAW_
if(self){
XGR_LineTo(getX() + x - 1,getY() + y - 1,sx + 2,2,SQ_SYSCOLOR + 7);
XGR_LineTo(getX() + x - 1,getY() + y + sy,sx + 2,2,SQ_SYSCOLOR + 7);
XGR_LineTo(getX() + x - 1,getY() + y,sy,3,SQ_SYSCOLOR + 7);
XGR_LineTo(getX() + x + sx,getY() + y,sy,3,SQ_SYSCOLOR + 7);
XGR_LineTo(getX() + x,getY() + y,sx,2,SQ_SYSCOLOR + 1);
XGR_LineTo(getX() + x + sx - 1,getY() + y,sy,3,SQ_SYSCOLOR + 1);
XGR_LineTo(getX() + x,getY() + y + sy - 1,sx - 1,2,SQ_SYSCOLOR + 5);
XGR_LineTo(getX() + x,getY() + y + 1,sy - 2,3,SQ_SYSCOLOR + 5);
for(int i = 0;i < sy - 2;i++)
XGR_LineTo(getX() + x + 1,getY() + y + 1 + i,sx - 2,2,SQ_SYSCOLOR + 4);
}
#endif
sqElem::draw();
}
void sqBox::restore(int _x,int _y,int _sx,int _sy)
{
#ifdef _SELFDRAW_
XGR_LineTo(getX() + x,getY() + y,sx,2,SQ_SYSCOLOR + 1);
XGR_LineTo(getX() + x + sx - 1,getY() + y,sy,3,SQ_SYSCOLOR + 1);
XGR_LineTo(getX() + x,getY() + y + sy - 1,sx - 1,2,SQ_SYSCOLOR + 5);
XGR_LineTo(getX() + x,getY() + y + 1,sy - 2,3,SQ_SYSCOLOR + 5);
for(int i = 0;i < sy - 2;i++)
XGR_LineTo(getX() + x + 1,getY() + y + 1 + i,sx - 2,2,SQ_SYSCOLOR + 4);
#endif
}
sqButton::sqButton(sqElem* _owner,int _x,int _y,int _sx,int _sy,int _shift,int _pressed)
{
owner = _owner;
x = _x; y = _y; sx = _sx; sy = _sy;
pressed = _pressed; shift = _shift; set();
}
void sqButton::draw(int self)
{
#ifdef _SELFDRAW_
if(self){
XGR_Rectangle(getX() + x,getY() + y,sx,sy,SQ_SYSCOLOR + 4,SQ_SYSCOLOR + 4,XGR_FILLED);
XGR_LineTo(getX() + x - 1,getY() + y - 1,sx + 2,2,SQ_SYSCOLOR + 6);
XGR_LineTo(getX() + x + sx,getY() + y,sy,3,SQ_SYSCOLOR + 6);
XGR_LineTo(getX() + x - 1,getY() + y + sy,sx + 1,2,SQ_SYSCOLOR + 2);
XGR_LineTo(getX() + x - 1,getY() + y,sy,3,SQ_SYSCOLOR + 2);
}
#endif
sqElem::draw();
}
void sqButton::handler(sqEvent* e)
{
if(e -> code == E_LBMPRESS){
remove();
if(pressed) x += shift,y -= shift,set(++height);
else x -= shift,y += shift,set(--height);
pressed = 1 - pressed;
draw();
}
}
sqInputBox::sqInputBox(sqElem* _owner,int _x,int _y,int _sx,int _sy,sqFont* _font,char* _title)
: sqBox(_owner,0,0,0,0)
{
owner = _owner;
sx = _sx; sy = _sy;
x = _x - _sx/2; y = _y - _sy/2;
// if(x < getX() + 4) x = getX() + 4;
// if(y < getY() + 2) y = getY() + 2;
// if(x + sx + 2 >= getRX()) x = getRX() - sx - 2;
// if(y + sy + 4 >= getRY()) y = getRY() - sy - 4;
set();
title = _title;
font = _font;
KeyTrapObj = this;
}
void sqInputBox::close(void)
{
sqElem* o = KeyTrapObj = owner;
QuantObj = owner;
*o - this;
o -> draw();
}
void sqInputBox::keytrap(int key)
{
switch(key){
case VK_F10:
message(M_ACCEPT);
close();
break;
case VK_ESCAPE:
message(M_CANCEL);
close();
break;
default:
if(obj) obj -> keytrap(key);
// owner -> keytrap(key);
break;
}
}
void sqInputBox::message(int code,sqElem* object)
{
switch(code){
case M_CHOICE:
case M_NEXTOBJ:
obj -> deactivate();
obj = obj -> next;
obj -> activate();
break;
case M_PREVOBJ:
obj -> deactivate();
obj = obj -> prev;
obj -> activate();
break;
case M_SETOBJ:
if(object != obj){
if(obj) obj -> deactivate();
obj = object;
obj -> activate();
}
break;
case M_DEACTIVATE:
obj -> deactivate();
obj = object;
break;
}
}
void sqInputBox::draw(int self)
{
sqBox::draw(self);
#ifdef _SELFDRAW_
if(self && title){
XGR_Rectangle(getX() + x + 1,getY() + y + 1,sx - 2,font -> sy,SQ_SYSCOLOR + 2,SQ_SYSCOLOR + 2,XGR_FILLED);
font -> draw(getX() + x + 1 + (sx - 2 - font -> sx*strlen(title))/2,getY() + y + 1,(unsigned char*)title,SQ_SYSCOLOR + 6,SQ_SYSCOLOR + 2);
XGR_LineTo(getX() + x,getY() + y + 1 + font -> sy,sx,2,SQ_SYSCOLOR + 6);
XGR_LineTo(getX() + x,getY() + y + 2 + font -> sy,sx,2,SQ_SYSCOLOR + 1);
}
#endif
}
void sqInputBox::restore(int _x,int _y,int _sx,int _sy)
{
#ifdef _SELFDRAW_
XGR_LineTo(_x,_y + 2,_sy - 2,3,SQ_SYSCOLOR + 4);
XGR_LineTo(_x + 1,_y + _sy - 1,_sx - 1,2,SQ_SYSCOLOR + 4);
#endif
}
void sqset2null(unsigned char* s,int l,int d)
{
memset(s,' ',l);
if(d > 0){
memset(s + l - d - 2,'0',d + 2);
s[l - d - 1] = '.';
}
else
s[l - 1] = '0';
}
sqInputString::sqInputString(sqElem* _owner,int _x,int _y,int _size,sqFont* _font,unsigned char* _str,int _len,int _type,int _dec)
{
owner = _owner;
x = _x; y = _y; size = _size; font = _font;
sy = font -> sy;
if(!(_type & T_FIELD)) sy += 4;
if(!_len)
len = (_size - 6)/_font -> sx;
else {
len = _len;
if(size < 0) size = len*font -> sx;
if(!(_type & T_FIELD)) size += 9;
}
type = _type; dec = _dec;
if(!(type & T_FIELD))
offset = (size - len*_font -> sx - 6)/2;
else
offset = 0;
str = new unsigned char[len + 1 + 64];
memset(str,' ',len);
str[len] = '\0';
if(_str){
if(type & T_NUMERIC)
memcpy((char*)str + len - strlen((char*)_str),(char*)_str,strlen((char*)_str));
else
memcpy((char*)str,(char*)_str,len);
// if(strlen((char*)_str) < len)
// memset(str + strlen((char*)_str),' ',len - strlen((char*)_str));
// if(type & T_NUMERIC){
// if(str[len - 1 - dec] == ' ' || !str[len - 1 - dec]) sqset2null(str,len,dec);
// }
}
savestr = new unsigned char[len];
index = blink = clen = 0;
fstatus = 1;
if(!(type & T_FIELD))
set();
else
set(0);
}
void sqInputString::draw(int self)
{
if(!(type & T_FIELD)){
XGR_Rectangle(getX() + x,getY() + y,size,font -> sy + 4,SQ_SYSCOLOR + 6 - (height - 1),SQ_SYSCOLOR + 6 - (height - 1),XGR_FILLED);
font -> draw(getX() + x + 2 + offset,getY() + y + 2,str,SQ_SYSCOLOR,SQ_SYSCOLOR + 6 - (height - 1));
sqElem::draw();
}
else
if(QuantObj == this)
font -> draw(getX() + x,getY() + y,str,SQ_SYSCOLOR,SQ_SYSCOLOR + 6);
else
font -> draw(getX() + x,getY() + y,str,SQ_SYSCOLOR,SQ_SYSCOLOR + 5);
}
void sqInputString::quant(void)
{
static int last = 0;
int t = CLOCK(),c,cdy;
if(last != t){
if(!(t%2)){
if(!(type & T_FIELD)){
c = (blink) ? SQ_SYSCOLOR : (SQ_SYSCOLOR + 6 - (height - 1));
cdy = insert ? 1 : 9;
XGR_Rectangle(getX() + x + 2 + offset + index*font -> sx,getY() + y + 2 + font -> sy - cdy,font -> sx,cdy + 1,c,c,XGR_FILLED);
if(!insert && !blink) font -> drawchar(getX() + x + 2 + offset + index*font -> sx,getY() + y + 2,str[index],SQ_SYSCOLOR,SQ_SYSCOLOR + 6 - (height - 1));
}
else {
c = (blink) ? SQ_SYSCOLOR : SQ_SYSCOLOR + 6;
cdy = insert ? 2 : 10;
XGR_Rectangle(getX() + x + index*font -> sx,getY() + y + font -> sy - cdy,font -> sx,cdy,c,c,XGR_FILLED);
if(!blink) font -> drawchar(getX() + x + index*font -> sx,getY() + y,str[index],SQ_SYSCOLOR,SQ_SYSCOLOR + 6);
}
blink = 1 - blink;
}
// else
// sqE -> put(E_REFRESH);
last = t;
}
}
void sqInputString::handler(sqEvent* e)
{
int i;
if(e -> code == E_LBMPRESS){
owner -> message(M_SETOBJ,this);
delcursor();
if(!(type & T_FIELD))
i = (e -> x - (getX() + x + 2))/font -> sx;
else
i = (e -> x - (getX() + x))/font -> sx;
if(i >= 0 && i < clen) index = i;
else index = (clen < len)?clen:len - 1;
}
}
void sqInputString::delcursor(void)
{
if(!(type & T_FIELD)){
XGR_Rectangle(getX() + x + 2 + offset + index*font -> sx,getY() + y + 2 + font -> sy - (insert?1:9),font -> sx,insert?2:10,SQ_SYSCOLOR + 6 - (height - 1),SQ_SYSCOLOR + 6 - (height - 1),XGR_FILLED);
if(!insert) font -> drawchar(getX() + x + 2 + offset + index*font -> sx,getY() + y + 2,str[index],SQ_SYSCOLOR,SQ_SYSCOLOR + 6 - (height - 1));
}
else {
XGR_Rectangle(getX() + x + index*font -> sx,getY() + y + font -> sy - (insert?2:10),font -> sx,insert?2:10,SQ_SYSCOLOR + 6,SQ_SYSCOLOR + 6,XGR_FILLED);
font -> drawchar(getX() + x + index*font -> sx,getY() + y,str[index],SQ_SYSCOLOR,SQ_SYSCOLOR + 6);
}
}
void sqInputString::keytrap(int key)
{
static int fhome,fend;
int newindex = -1;
int dp = ((type & T_NUMERIC) && dec > 0) ? len - dec - 1 : 0;
unsigned char c;
int xadd,yadd,col,i;
if(!(type & T_FIELD)){
xadd = 2 + offset;
yadd = 2;
col = 6 - (height - 1);
}
else {
xadd = yadd = 0;
col = 6;
}
switch(key){
case VK_TAB:
if(XKey.Pressed(VK_SHIFT))
owner -> message(M_PREVOBJ);
else
owner -> message(M_NEXTOBJ);
break;
case VK_DOWN:
owner -> message(M_NEXTOBJ);
break;
case VK_UP:
owner -> message(M_PREVOBJ);
break;
case VK_RETURN:
owner -> message(M_CHOICE);
return;
case VK_INSERT:
delcursor();
insert = 1 - insert;
break;
case VK_RSHIFT:
rus = 1 - rus;
break;
case VK_LEFT:
if(index){
newindex = index - 1;
if(newindex && XKey.Pressed(VK_CONTROL)){
if(!isalnum(str[newindex]))
while(newindex && !isalnum(str[newindex])) newindex--;
while(newindex && isalnum(str[newindex])) newindex--;
if(newindex) newindex++;
}
else
if(dp && newindex == dp) newindex--;
}
break;
case VK_RIGHT:
if(index < len - 1){
newindex = index + 1;
if(newindex < len - 1 && XKey.Pressed(VK_CONTROL)){
if(isalnum(str[newindex]))
while(newindex < len - 1 && isalnum(str[newindex])) newindex++;
while(newindex < len - 1 && !isalnum(str[newindex])) newindex++;
}
else
if(newindex == dp) newindex++;
}
break;
case VK_HOME:
if(fhome <= 0){
if(index) newindex = 0;
fhome = 2;
}
else {
for(i = 0;i < len;i++)
if(str[i] != ' ') break;
if(i != len) newindex = i;
}
break;
case VK_END:
if(fend <= 0){
if(index < len - 1) newindex = len - 1;
fend = 2;
}
else {
for(i = len - 2;i >= 0;i--)
if(str[i] != ' ') break;
if(i >= 0) newindex = i + 1;
}
break;
case VK_BACK:
if(XKey.Pressed(VK_CONTROL)){
memcpy(str,savestr,len);
font -> draw(getX() + x + xadd,getY() + y + yadd,str,SQ_SYSCOLOR,SQ_SYSCOLOR + col);
}
else
if(index){
newindex = index - 1;
if(!dp){
memmove(str + newindex,str + index,len - index);
str[len - 1] = ' ';
font -> draw(getX() + x + xadd + font -> sx*newindex,getY() + y + yadd,str + newindex,SQ_SYSCOLOR,SQ_SYSCOLOR + col);
}
else {
if(index < dp){
memmove(str + newindex,str + index,dp - index);
str[dp - 1] = ' ';
}
if(index > dp)
if(newindex == dp) str[--newindex] = ' ';
else {
memmove(str + newindex,str + index,len - index);
str[len - 1] = ' ';
}
font -> draw(getX() + x + xadd,getY() + y + yadd,str,SQ_SYSCOLOR,SQ_SYSCOLOR + col);
}
}
break;
case VK_DELETE:
if(!dp){
if(index != clen){
newindex = index;
memmove(str + index,str + index + 1,len - index - 1);
str[len - 1] = ' ';
font -> draw(getX() + x + xadd + font -> sx*index,getY() + y + yadd,str + index,SQ_SYSCOLOR,SQ_SYSCOLOR + col);
}
}
else {
newindex = index;
if(index < dp){
if(index < dp - 1) memmove(str + index,str + index + 1,dp - index - 1);
str[dp - 1] = ' ';
}
if(index > dp){
if(index < len - 1) memmove(str + index,str + index + 1,len - index - 1);
str[len - 1] = ' ';
}
font -> draw(getX() + x + xadd,getY() + y + yadd,str,SQ_SYSCOLOR,SQ_SYSCOLOR + col);
}
break;
default:
if(fstatus && !index){
memset(str,' ',len);
index = 0;
if(dp) sqset2null(str,len,dec);
clen = len;
draw();
}
c = key; // !
if(c == VK_SUBTRACT || c == VK_OEM_MINUS) c = '-';
if(!dp){
if((type & T_STRING) || ((type & T_NUMERIC) && !dec && ((isdigit(c) || c == ' ' || c == '-')))){
if(index < len - 1){
newindex = index + 1;
if(insert && index < len - 2) memmove(str + newindex,str + index,len - index - 1);
}
str[index] = c;
if(insert && index < len - 2)
font -> draw(getX() + x + xadd + index*font -> sx,getY() + y + yadd,str + index,SQ_SYSCOLOR,SQ_SYSCOLOR + col);
else
font -> drawchar(getX() + x + xadd + index*font -> sx,getY() + y + yadd,str[index],SQ_SYSCOLOR,SQ_SYSCOLOR + col);
}
}
else {
if(isdigit(c) || c == '.' || c == ' ' || c == '-'){
if(c == '.'){
newindex = dp + 1;
if(index && index < dp) memmove(str + dp - index,str,index), memset(str,' ',index);
if(!index || str[dp - 1] == ' ') memset(str,' ',dp - 1), str[dp - 1] = '0';
}
else {
if(index < dp - 1 && insert) memmove(str + index + 1,str + index,dp - index - 1);
if(index < dp) newindex = index + 1;
if(newindex == dp) newindex++;
if(index > dp && insert && index < len - 1) memmove(str + index + 1,str + index,len - index - 1), newindex = index + 1;
str[index] = c;
}
font -> draw(getX() + x + xadd,getY() + y + yadd,str,SQ_SYSCOLOR,SQ_SYSCOLOR + col);
}
}
}
if(newindex != -1){
delcursor();
blink = 1;
if(newindex != -1) index = newindex;
}
--fhome; --fend;
fstatus = 0;
}
void sqInputString::activate(int force)
{
// QuantObj = this;
memcpy(savestr,str,len);
if(force) remove();
if(!(type & T_FIELD))
set(1);
else
set(0);
if(force) draw();
}
void sqInputString::deactivate(void)
{
remove();
if(!(type & T_FIELD))
set(2);
else
set(0);
if(type & T_NUMERIC){
XBuffer ff;
ff < "%" <= len < "." <= dec < "f";
sprintf((char*)str,ff.GetBuf(),atof((char*)str));
}
draw();
}
char* sqInputString::getstr(void)
{
register int i = len - 1;
while(i && str[i] == ' ') i--;
i++;
char* s = new char[i + 1];
memcpy(s,str,i);
s[i] = '\0';
return s;
}
void sqInputString::setstr(unsigned char* s)
{
sqstrNcpy((char*)str,(char*)s,len);
clen = index = strlen((char*)str) - 1;
while(str[index] == ' ') index--;
if(index) index++;
str[index] = '\0';
clen = index;
if(clen == len) clen--,index--;
}
sqField::sqField(sqElem* _owner,char* _prompt,int _x,int _y,int _size,sqFont* _font,unsigned char* _str,int _len,int _type,int _dec)
: sqInputString(_owner,_x + strlen(_prompt)*_font -> sx + 3,_y,_size - strlen(_prompt)*_font -> sx - 3,_font,_str,_len,_type,_dec)
{
prompt = (unsigned char*)strdup(_prompt);
x0 = _x;
y0 = _y + 2;
}
void sqField::draw(int self)
{
font -> draw(getX() + x0,getY() + y0,prompt,SQ_SYSCOLOR,SQ_SYSCOLOR + 4);
sqInputString::draw();
}
sqTextButton::sqTextButton(sqElem* _owner,int _x,int _y,char* _text,sqFont* _font,int _sx)
{
owner = _owner;
x = _x; y = _y;
text = _text;
font = _font;
if(_sx)
sx = _sx;
else
sx = strlen(_text)*_font -> sx + 6;
sy = font -> sy + 4;
set();
offset = (sx - strlen(_text)*_font -> sx)/2;
}
void sqTextButton::draw(int self)
{
const int mask[2*23] = { 6,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,4,3,2,0,
6,7,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,3,2,0 };
int ind = (height == 2)?0:2;
// c_putspr(getX() + x - 6,getY() + y - 3,ButElem[ind] -> x_size,ButElem[ind] -> y_size,ButElem[4*(2 - height) + ind] -> data,BLACK_FON);
// c_putspr(getX() + x + sx - 2,getY() + y - 3,ButElem[ind + 1] -> x_size,ButElem[ind + 1] -> y_size,ButElem[4*(2 - height) + ind + 1] -> data,BLACK_FON);
for(int i = 0;i < 23;i++)
XGR_LineTo(getX() + x + 2,getY() + y - 3 + i,sx - 4,2,SQ_SYSCOLOR + mask[23*(height - 1) + i]);
if(!ind)
XGR_LineTo(getX() + x + 2,getY() + y + 20,sx - 4,2,SQ_SYSCOLOR);
font -> draw(getX() + x + offset,getY() + y,(unsigned char*)text,SQ_SYSCOLOR,SQ_SYSCOLOR + 7 - height);
}
void sqTextButton::handler(sqEvent* e)
{
if(e -> code == E_LBMPRESS)
owner -> message(M_SETOBJ,this);
}
void sqTextButton::keytrap(int key)
{
switch(key){
case VK_TAB:
if(XKey.Pressed(VK_SHIFT))
owner -> message(M_PREVOBJ);
else
owner -> message(M_NEXTOBJ);
break;
case VK_LEFT:
case VK_UP:
owner -> message(M_PREVOBJ);
break;
case VK_RIGHT:
case VK_DOWN:
owner -> message(M_NEXTOBJ);
break;
case VK_RETURN:
case VK_SPACE:
owner -> message(M_CHOICE);
break;
}
}
void sqTextButton::activate(int force)
{
// QuantObj = this;
if(force) remove();
set(1);
if(force) draw();
}
void sqTextButton::deactivate(void)
{
remove();
set(2);
draw();
}
void sqTextButton::remove(void)
{
XGR_LineTo(getX() + x - 3,getY() + y + 20,sx + 4,2,SQ_SYSCOLOR + 4);
}

252
surmap/sqicore.cpp Normal file
View File

@@ -0,0 +1,252 @@
/*
Simple-Quick Interface by K-Division::KranK
All Rights Reserved (C)1995
(Core)
*/
#include "..\global.h"
#pragma hdrstop
#include "sqint.h"
extern int TrackBuild;
/* ---------------------------- EXTERN SECTION ----------------------------- */
/* --------------------------- PROTOTYPE SECTION --------------------------- */
void LMousePress(int, int, int);
void LMouseUnpress(int, int, int);
void RMousePress(int, int, int);
void RMouseUnpress(int, int, int);
void LMouseMov(int, int, int);
void RMouseMov(int, int, int);
void LMouseDouble(int, int, int);
void RMouseDouble(int, int, int);
/* --------------------------- DEFINITION SECTION -------------------------- */
sqEventQueue* sqE;
sqEventQueue* sqKey;
sqScreen* sqScr;
sqElem* QuantObj;
sqElem* KeyTrapObj;
int SQ_SYSCOLOR;
sqScreen::sqScreen(int _x,int _y,int _sx,int _sy)
: sqElem(0,0,0,0,0)
{
x = _x; y = _y; sx = _sx; sy = _sy;
set(0);
// XGR_MouseObj.SetClip(x + XGR_MouseObj.SizeX/2, y + XGR_MouseObj.SizeY/2,x + sx - XGR_MouseObj.SizeX/2, y + sy - XGR_MouseObj.SizeY/2);
}
static unsigned char XMouseMask[64] = {
255,255,255,255,255,255,255,255,
255,0,0,255,255,0,0,255,
255,0,0,0,0,0,0,255,
255,255,0,0,0,0,255,255,
255,255,0,0,0,0,255,255,
255,0,0,0,0,0,0,255,
255,0,0,255,255,0,0,255,
255,255,255,255,255,255,255,255
};
void sqInitMouse(void)
{
XGR_MouseInit(XGR_MAXX/2,XGR_MAXY/2,8,8,1,XMouseMask);
XGR_MouseSetSpot(4,4);
XGR_MouseSetPressHandler(XGM_LEFT_BUTTON,LMousePress);
XGR_MouseSetUnPressHandler(XGM_LEFT_BUTTON,LMouseUnpress);
XGR_MouseSetPressHandler(XGM_RIGHT_BUTTON,RMousePress);
XGR_MouseSetUnPressHandler(XGM_RIGHT_BUTTON,RMouseUnpress);
XGR_MouseSetDblHandler(XGM_LEFT_BUTTON,LMouseDouble);
XGR_MouseSetDblHandler(XGM_RIGHT_BUTTON,RMouseDouble);
XGR_MouseSetPos(XGR_MAXX/2,XGR_MAXY/2);
}
void sqRestoreCursor(void)
{
// XGR_MouseObj.SetCursor(XMouseMask,1,8,8);
}
void LMousePress(int, int x, int y)
{
sqE -> put(E_LBMPRESS,E_REGION,x,y);
}
void LMouseUnpress(int, int x, int y)
{
sqE -> put(E_LBMUNPRESS,E_REGION,x,y);
}
void RMousePress(int, int x, int y)
{
sqE -> put(E_RBMPRESS,E_REGION,x,y);
}
void RMouseUnpress(int, int x, int y)
{
sqE -> put(E_RBMUNPRESS,E_REGION,x,y);
}
void LMouseDouble(int, int x, int y)
{
sqE -> put(E_LBMDOUBLE,E_REGION,x,y);
}
void RMouseDouble(int, int x, int y)
{
sqE -> put(E_RBMDOUBLE,E_REGION,x,y);
}
void sqSetPalette(char* pal)
{
for(int i = 0;i < 8;i++){
pal[3*(SQ_SYSCOLOR + i) + 0] = 1 + i*8;
pal[3*(SQ_SYSCOLOR + i) + 1] = 3 + i*8;
pal[3*(SQ_SYSCOLOR + i) + 2] = 7 + i*8;
}
}
void sqFont::init(void* d)
{
char* p = (char*)d;
memcpy(this,p,8);
data = new void*[num];
for(int i = 0;i < num;i++)
data[i] = p + 8 + sy*i;
}
void sqFont::draw(int x,int y,unsigned char* s,int fore,int back)
{
while(*s){
drawchar(x,y,*s,fore,back);
s++;
x += sx;
}
}
void sqFont::drawtext(int x,int y,char* s,int fore,int back)
{
char c;
int i = x;
while((c = *s) != 0){
switch(c){
default:
drawchar(i,y,*s,fore,back);
i += sx;
break;
case '\n':
y += sy;
i = x;
break;
case '\t':
i += 4*sx;
break;
}
s++;
}
}
void sqFont::drawchar(int x,int y,int ch,int fore,int back)
{
if(x < 0 || y < 0 || x + sx >= XGR_MAXX || y + sy >= XGR_MAXY)
return;
unsigned char* p = (unsigned char*)data[ch];
int i,j,m;
for(j = 0;j < sy;j++)
for(i = 0,m = 1 << sx;i < sx;i++,m >>= 1){
if(p[j] & m) XGR_SetPixel(x + i,y + j,fore);
else
if(back != -1) XGR_SetPixel(x + i,y + j,back);
}
}
void sqInit(int col0)
{
sqInitMouse();
SQ_SYSCOLOR = col0;
sqE = new sqEventQueue(256);
sqKey = new sqEventQueue(128);
sqScr = new sqScreen(0,0,XGR_MAXX,XGR_MAXY);
}
#ifdef _SURMAP_
void sqQuant(void)
{
int isFlush = 0;
sqEvent* event = sqKey -> get();
if(event){
// do {
KeyTrapObj -> keytrap(event -> code);
event = sqKey -> get();
// } while(event);
isFlush = 1;
}
event = sqE -> get();
if(event){
do {
sqScr -> process(event);
event = sqE -> get();
} while(event);
isFlush = 1;
}
if(TrackBuild) isFlush = 1;
if(isFlush && KeyTrapObj) KeyTrapObj -> draw();
if(QuantObj) QuantObj -> quant();
if(isFlush && KeyTrapObj){
XGR_MouseHide();
KeyTrapObj -> flush();
XGR_MouseShow();
}
}
#endif
#ifdef _ROAD_
void sqQuant(void)
{
int isFlush = 0;
sqEvent* event = sqKey -> get();
if(event){
if(isMouse) XGR_MouseObj.hide();
do {
KeyTrapObj -> keytrap(event -> code);
event = sqKey -> get();
} while(event);
if(isMouse) XGR_MouseObj.show();
isFlush = 1;
}
event = sqE -> get();
if(event){
if(isMouse) XGR_MouseObj.hide();
do {
sqScr -> process(event);
event = sqE -> get();
} while(event);
if(isMouse) XGR_MouseObj.show();
isFlush = 1;
}
// sqScr -> quant();
// if(isFlush && KeyTrapObj) KeyTrapObj -> draw();
if(QuantObj){
isFlush = 1;
QuantObj -> quant();
}
// if(isFlush && KeyTrapObj) KeyTrapObj -> flush();
}
#endif
#if !defined(_ROAD_) && !defined(_SURMAP_)
void sqScreen::keytrap(int key){}
void sqScreen::handler(sqEvent* e){}
void sqScreen::draw(int mode){}
#endif

554
surmap/sqimenu.cpp Normal file
View File

@@ -0,0 +1,554 @@
/*
Simple-Quick Interface by K-Division::KranK
All Rights Reserved (C)1995
(Menu)
*/
#include "..\global.h"
#pragma hdrstop
#include "sqint.h"
/* ---------------------------- EXTERN SECTION ----------------------------- */
/* --------------------------- PROTOTYPE SECTION --------------------------- */
/* --------------------------- DEFINITION SECTION -------------------------- */
const int MAXSEEK = 32;
const int SEEKDELAY = 10;
sqMenuBar::sqMenuBar(unsigned char* s,sqPopupMenu* owner,int _status,int _value,int _rec)
{
int m = owner -> margin;
int sl = s?strlen((char*)s):0;
int l = sl + 2*m;
if(l > owner -> len) owner -> setlen(l);
else l = owner -> len;
data = new unsigned char[l + 1];
original_data = (unsigned char*)strdup((char*)s);
memset(data,' ',m);
if(s) memcpy(data + m,s,sl);
memset(data + m + sl,' ',l - sl - m);
data[l] = '\0';
if((status = _status) != 0) *data = 4;
value = _value;
rec = _rec;
}
void sqMenuBar::replace(sqPopupMenu* owner,unsigned char* s)
{
int m = owner -> margin;
int sl = s?strlen((char*)s):0;
int l = sl + 2*m;
if(l > owner -> len){
owner -> setlen(l);
delete data;
data = new unsigned char[l + 1];
}
else
l = owner -> len;
if(s) memcpy(data + m,s,sl);
memset(data + m + sl,' ',l - sl - m);
data[l] = '\0';
}
sqPopupMenu::sqPopupMenu(sqElem* _owner,int _x,int _y,int _visibars,sqFont* _font,int _len0,int _margin)
{
owner = _owner;
x = _x; y = _y;
sx = sy = 0;
visibars = _visibars;
margin = _margin;
font = _font;
len = len0 = _len0;
if(_len0) sx = _len0*_font -> sx, set();
maxbars = topbar = nbar = seekcounter = 0;
first = pointer = insert = NULL;
seeklen = 0;
seekbuf = new unsigned char[MAXSEEK + 1];
}
sqPopupMenu& sqPopupMenu::operator* (sqMenuBar* obj)
{
if(!first){
first = pointer = obj;
first -> next = first -> prev = NULL;
}
else {
obj -> prev = insert;
if(insert){
obj -> next = insert -> next;
if(insert -> next) insert -> next -> prev = obj;
insert -> next = obj;
}
else {
obj -> next = first;
first -> prev = obj;
first = obj;
}
}
insert = obj;
maxbars++;
sy = MIN(maxbars,visibars)*font -> sy; set(height);
return *this;
}
void sqPopupMenu::disconnect(sqMenuBar* obj,sqMenuBar** del)
{
if(obj == insert)
if(obj -> next) insert = obj -> next;
else insert = obj -> prev;
if(obj == first){
if(obj -> next) obj -> next -> prev = NULL;
first = obj -> next;
}
else {
obj -> prev -> next = obj -> next;
if(obj -> next) obj -> next -> prev = obj -> prev;
}
if(!del)
delete obj;
else {
obj -> next = *del;
*del = obj;
}
maxbars--;
sy = MIN(maxbars,visibars)*font -> sy; set(height);
}
void sqPopupMenu::setlen(int l)
{
sqMenuBar* p = first;
unsigned char* s;
if(l > len)
while(p){
s = new unsigned char[l + 1];
memcpy(s,p -> data,len);
memset(s + len,' ',l - len);
s[l] = '\0';
delete p -> data;
p -> data = s;
p = p -> next;
}
else
if(l < len)
while(p){
p -> data[l] = '\0';
p = p -> next;
}
len = l;
sx = len*font -> sx; set(height);
}
void sqPopupMenu::draw(int self)
{
nbar = getptr(pointer);
sqMenuBar* p = getbar(topbar);
int i = y,j = 0;
while(p && j < visibars){
if(p == pointer)
font -> draw(getX() + x,getY() + i,p -> data,SQ_SYSCOLOR,SQ_SYSCOLOR + 6 + (2 - height));
else
font -> draw(getX() + x,getY() + i,p -> data,SQ_SYSCOLOR,SQ_SYSCOLOR + 5);
i += font -> sy; j++;
p = p -> next;
}
sqElem::draw();
owner -> message(M_CHANGEOPTION);
}
sqMenuBar* sqPopupMenu::getbar(int n)
{
sqMenuBar* p = first;
while(p){
if(!n) return p;
p = p -> next;
n--;
}
return NULL;
}
int sqPopupMenu::getptr(sqMenuBar* b)
{
sqMenuBar* p = first;
int i = 0;
while(p){
if(p == b) return i;
p = p -> next;
i++;
}
return 0;
}
void sqPopupMenu::keytrap(int key)
{
switch(key){
case VK_TAB:
if(XKey.Pressed(VK_SHIFT))
owner -> message(M_PREVOBJ);
else
owner -> message(M_NEXTOBJ);
seeklen = 0;
break;
case VK_F7:
case VK_INSERT:
owner -> message(M_INSERT);
break;
case VK_F8:
case VK_DELETE:
owner -> message(M_DELETE);
break;
case VK_SPACE:
owner -> message(M_SETOPTION);
break;
case VK_RETURN:
if(XKey.Pressed(VK_SHIFT)){
if(seeklen)
if(pointer -> next)
seek(pointer -> next);
else
seek(first);
}
else {
seeklen = 0;
owner -> message(M_CHOICE);
}
break;
case VK_RSHIFT:
sqInputString::rus = 1 - sqInputString::rus;
break;
case VK_UP:
if(!pointer -> prev){
pointer = getbar(maxbars - 1);
topbar = (maxbars >= visibars)?maxbars - visibars:0;
}
else {
if(pointer == getbar(topbar)) topbar--;
pointer = pointer -> prev;
}
draw();
seeklen = 0;
break;
case VK_DOWN:
if(!pointer -> next){
pointer = first;
topbar = 0;
}
else {
if(getptr(pointer) - topbar + 1 == visibars) topbar++;
pointer = pointer -> next;
}
draw();
seeklen = 0;
break;
case VK_HOME:
if(pointer){
pointer = first;
topbar = 0;
draw();
}
seeklen = 0;
break;
case VK_END:
if(pointer -> next){
pointer = getbar(maxbars - 1);
topbar = (maxbars >= visibars)?maxbars - visibars:0;
draw();
}
seeklen = 0;
break;
case VK_LEFT:
if(pointer != getbar(topbar)){
pointer = getbar(topbar);
draw();
}
seeklen = 0;
break;
case VK_RIGHT:
if(pointer != getbar(topbar + MIN(visibars,maxbars) - 1)){
pointer = getbar(topbar + MIN(visibars,maxbars) - 1);
draw();
}
seeklen = 0;
break;
case VK_PRIOR:
if(pointer){
topbar = getptr(pointer) - visibars;
if(topbar < 0) topbar = 0;
pointer = getbar(topbar);
draw();
}
seeklen = 0;
break;
case VK_NEXT:
if(pointer != getbar(maxbars - 1)){
topbar = getptr(pointer) + visibars;
if(topbar >= maxbars) topbar = maxbars - 1;
pointer = getbar(topbar);
topbar -= MIN(maxbars,visibars) - 1;
draw();
}
seeklen = 0;
break;
case VK_OEM_PLUS:
owner -> message(M_SETALL);
break;
case VK_OEM_MINUS:
owner -> message(M_UNSETALL);
break;
default:
if(CLOCK() - seekcounter > SEEKDELAY) seeklen = 0;
if(seeklen <= MAXSEEK){
seekbuf[seeklen++] = key; // !
seek(pointer);
seekcounter = CLOCK();
}
break;
}
}
void sqPopupMenu::handler(sqEvent* e)
{
int n;
sqMenuBar* pb;
switch(e -> code){
case E_LBMPRESS:
// if( XGR_MouseObj.GetLeftClip() != getX() + x + XGR_MouseObj.SizeX/2){
// XGR_MouseObj.SetClip(getX() + x + XGR_MouseObj.SizeX/2, getY() + y + XGR_MouseObj.SizeY/2, getX() + x + sx - XGR_MouseObj.SizeX/2, getY() + y + sy - XGR_MouseObj.SizeY/2);
// XGR_MouseObj.left = getX() + x + XGR_MouseObj.SizeX/2;
// XGR_MouseObj.top = getY() + y + XGR_MouseObj.SizeY/2;
// XGR_MouseObj.right = getX() + x + sx - XGR_MouseObj.SizeX/2;
// XGR_MouseObj.bottom = getY() + y + sy - XGR_MouseObj.SizeY/2;
// XGR_MouseObj.change();
// }
owner -> message(M_SETOBJ,this);
n = topbar + (e -> y - (getY() + y))/font -> sy;
if(n >= maxbars) n = maxbars - 1;
pb = pointer;
pointer = getbar(n);
if(XGR_MouseObj.LastPosY > XGR_MouseObj.PosY && topbar + visibars - 1 == getptr(pointer)){
if(pointer -> next){
topbar++;
pointer = pointer -> next;
}
}
else
if(XGR_MouseObj.LastPosY < XGR_MouseObj.PosY && topbar == getptr(pointer)){
if(pointer -> prev){
topbar--;
pointer = pointer -> prev;
}
}
if(pointer != pb) draw();
break;
case E_LBMUNPRESS:
// XGR_MouseObj.SetClip(sqScr -> x + XGR_MouseObj.SizeX/2, sqScr -> y + XGR_MouseObj.SizeY/2, sqScr -> x + sqScr -> sx - XGR_MouseObj.SizeX/2, sqScr -> y + sqScr -> sy - XGR_MouseObj.SizeY/2);
// XGR_MouseObj.left = sqScr -> x + XGR_MouseObj.SizeX/2;
// XGR_MouseObj.right = sqScr -> x + sqScr -> sx - XGR_MouseObj.SizeX/2;
// XGR_MouseObj.top = sqScr -> y + XGR_MouseObj.SizeY/2;
// XGR_MouseObj.bottom = sqScr -> y + sqScr -> sy - XGR_MouseObj.SizeY/2;
// XGR_MouseObj.change();
break;
case E_LBMDOUBLE:
owner -> message(M_SETOBJ,this);
n = topbar + (e -> y - (getY() + y))/font -> sy;
if(n >= maxbars) n = maxbars - 1;
pointer = getbar(n);
draw();
owner -> message(M_SETOPTION);
break;
}
}
void sqPopupMenu::activate(int force)
{
// QuantObj = this;
if(force) remove();
set(1);
if(force) draw();
}
void sqPopupMenu::deactivate(void)
{
remove();
set(2);
draw();
}
void sqPopupMenu::seek(sqMenuBar* p0,int force)
{
sqMenuBar* p = p0;
while(p){
if(!memicmp(p -> data + margin,seekbuf,seeklen)){
setpointer(p,force);
return;
}
p = p -> next;
}
p = first;
while(p != p0){
if(!memicmp(p -> data + margin,seekbuf,seeklen)){
setpointer(p,force);
return;
}
p = p -> next;
}
}
void sqPopupMenu::setpointer(sqMenuBar* p,int force)
{
int dif = getptr(pointer) - topbar;
pointer = p;
topbar = getptr(p) - dif;
if(topbar < 0) topbar = 0;
else topbar = MIN(topbar,maxbars - MIN(maxbars,visibars));
if(force) draw();
}
void sqPopupMenu::free(void)
{
sqMenuBar* p = first,*p0;
while(p){
p0 = p -> next;
delete p;
p = p0;
}
if(first){
maxbars = topbar = nbar = seekcounter = 0;
first = pointer = insert = NULL;
len = len0;
seeklen = 0;
}
}
sqMultiMenu::sqMultiMenu(sqElem* _owner,int _x,int _y,int _visibars,sqFont* _font,int _maxlen)
{
owner = _owner;
x = _x; y = _y;
maxlen = _maxlen;
sx = _maxlen*_font -> sx + 2;
sy = _font -> sy + 8 + _visibars*_font -> sy + 2;
set(0);
*this + (edit = new sqInputString(this,2,0,_font -> sx*(_maxlen + 1),_font,(unsigned char*)NULL,_maxlen));
*this + (list = new sqPopupMenu(this,2,_font -> sy + 8,_visibars,_font,_maxlen + 2));
obj = NULL;
deleted = NULL;
}
void sqMultiMenu::keytrap(int key)
{
obj -> keytrap(key);
}
void sqMultiMenu::activate(int force)
{
obj = list;
obj -> activate();
}
void sqMultiMenu::deactivate(void)
{
obj -> deactivate();
obj = NULL;
}
void sqMultiMenu::message(int code,sqElem* object)
{
sqMenuBar* p;
switch(code){
case M_NEXTOBJ:
obj -> deactivate();
if(obj == edit){
obj = list;
obj -> activate();
}
else
owner -> message(M_NEXTOBJ);
break;
case M_PREVOBJ:
obj -> deactivate();
if(obj == edit){
obj = list;
obj -> activate();
}
else
owner -> message(M_PREVOBJ);
break;
case M_SETOBJ:
if(object != obj){
if((obj == edit && object == list) || (obj == list && object == edit))
obj -> deactivate();
else
owner -> message(M_DEACTIVATE,this);
obj = object;
obj -> activate();
}
break;
case M_CHOICE:
if(obj == edit){
list -> pointer -> replace(list,edit -> str);
obj -> deactivate();
obj = list;
obj -> activate();
}
else {
obj -> deactivate();
obj = edit;
obj -> activate();
}
break;
case M_SETOPTION:
list -> pointer -> status = 1 - list -> pointer -> status;
if(list -> pointer -> status) *list -> pointer -> data = 4;
else *list -> pointer -> data = ' ';
list -> draw();
break;
case M_CHANGEOPTION:
edit -> setstr(list -> pointer -> data + list -> margin);
edit -> draw();
owner -> message(M_CHANGEOPTION);
break;
case M_DELETE:
if(list -> maxbars > 1){
if(list -> pointer -> next) list -> insert = list -> pointer -> next;
else list -> insert = list -> pointer -> prev;
list -> remove();
list -> disconnect(list -> pointer,&deleted);
list -> pointer = list -> insert;
list -> draw();
}
break;
case M_INSERT:
if(!edit -> insert) list -> insert = list -> pointer;
else list -> insert = list -> pointer -> prev;
*list * new sqMenuBar((unsigned char*)NULL,list);
list -> pointer = list -> insert;
list -> draw();
message(M_CHOICE);
break;
case M_SETALL:
p = list -> first;
while(p){
*p -> data = 4;
p -> status = 1;
p = p -> next;
}
list -> draw();
break;
case M_UNSETALL:
p = list -> first;
while(p){
*p -> data = ' ';
p -> status = 0;
p = p -> next;
}
list -> draw();
break;
}
}
void sqMultiMenu::restore(int _x,int _y,int _sx,int _sy)
{
XGR_Rectangle(_x,_y,_sx,_sy,SQ_SYSCOLOR + 4,SQ_SYSCOLOR + 4,XGR_FILLED);
}

381
surmap/sqint.h Normal file
View File

@@ -0,0 +1,381 @@
/*
Simple-Quick Interface by K-Division::KranK
All Rights Reserved (C)1995
*/
#ifndef _SQINT_
#define _SQINT_
#ifdef _SURMAP_
#define _SELFDRAW_
#endif
/* ------------------------- Changeable parameters -------------------------- */
/* ----------------------------- Useful macros ------------------------------ */
#ifndef MIN
#define MIN(a,b) (((a) < (b))?(a):(b))
#define MAX(a,b) (((a) > (b))?(a):(b))
#define CLOCK() (clock()*18/CLOCKS_PER_SEC)
#endif
/* ---------------------------- Internal consts ----------------------------- */
#define E_REGION 0
#define E_COMMON 1
#define E_REFRESH 10
#define E_LBMPRESS 11
#define E_RBMPRESS 12
#define E_LBMUNPRESS 13
#define E_RBMUNPRESS 14
#define E_LBMMOV 15
#define E_RBMMOV 16
#define E_LBMDOUBLE 17
#define E_RBMDOUBLE 18
#define M_NEXTOBJ 1
#define M_PREVOBJ 2
#define M_SETOBJ 3
#define M_DEACTIVATE 4
#define M_CHOICE 5
#define M_SETOPTION 6
#define M_INSERT 7
#define M_DELETE 8
#define M_CHANGEOPTION 9
#define M_SETALL 10
#define M_UNSETALL 11
#define M_ACCEPT 12
#define M_CANCEL 13
#define T_STRING 1
#define T_NUMERIC 2
#define T_FIELD 0x0100
/* -------------------------------- Structs --------------------------------- */
extern int SQ_SYSCOLOR;
const int SYSCOLOR = 159;
struct sqFont {
short num;
unsigned char first,last;
short sx,sy;
void** data;
void init(void* d);
void draw(int x,int y,unsigned char* s,int fore = SQ_SYSCOLOR,int back = SQ_SYSCOLOR + 5);
void draw(int x,int y,char* s,int fore = SYSCOLOR,int back = -1){ draw(x,y,(unsigned char*)s,fore,back); }
void drawtext(int x,int y,char* s,int fore = SQ_SYSCOLOR,int back = SQ_SYSCOLOR + 5);
void drawchar(int x,int y,int ch,int fore = SQ_SYSCOLOR,int back = SQ_SYSCOLOR + 5);
};
struct sqEvent {
int code;
int type;
int x,y;
void* pointer;
int value;
};
struct sqEventQueue {
sqEvent* queue;
int max;
int top,bottom;
sqEventQueue(int _max){ queue = new sqEvent[max = _max]; top = bottom = 0; }
void put(int _code);
void put(int _code,int _type,int _x,int _y);
void put(int _code,int _type,int _x,int _y,void* _pointer,int _value);
sqEvent* get(void);
};
struct sqElem {
sqElem* owner;
sqElem* tail;
sqElem* next;
sqElem* prev;
int dxl,dyl,dxr,dyr;
int xl,yl,xr,yr;
int height;
sqElem(int _height = 2,int _dxl = -1,int _dyl = -1,int _dxr = 1,int _dyr = 1);
virtual ~sqElem(void){}
sqElem& operator+ (sqElem* e);
sqElem& operator- (sqElem* e);
void reject(void);
virtual void draw(int self = 1);
virtual int* getXY(void);
virtual void handler(sqEvent* e);
virtual void accept(void);
virtual void restore(int _x,int _y,int _sx,int _sy);
virtual void remove(void);
virtual int process(sqEvent* event);
virtual void keytrap(int key);
virtual void quant(void);
virtual void message(int code,sqElem* object = NULL);
virtual void activate(int force = 1);
virtual void deactivate(void);
virtual void flush(void);
void set(int _height = 2);
int ishere(int x,int y);
int getX(void){ if(owner) return owner -> getX() + owner -> xl - owner -> dxl; return 0; }
int getY(void){ if(owner) return owner -> getY() + owner -> yl - owner -> dyl; return 0; }
int getRX(void){ if(owner) return owner -> getX() + owner -> xr + owner -> dxr; return 0; }
int getRY(void){ if(owner) return owner -> getY() + owner -> yr + owner -> dyr; return 0; }
};
struct sqScreen : sqElem {
int x,y,sx,sy;
sqScreen(int _x,int _y,int _sx,int _sy);
virtual int* getXY(void){ return &x; }
virtual void keytrap(int key);
virtual void handler(sqEvent* e);
virtual void draw(int self = 1);
};
struct sqBox : sqElem {
int x,y,sx,sy;
sqBox(sqElem* _owner,int _x,int _y,int _sx,int _sy)
{ x = _x; y = _y; sx = _sx; sy = _sy; set(); }
virtual int* getXY(void){ return &x; }
virtual void draw(int self = 1);
virtual void restore(int _x,int _y,int _sx,int _sy);
};
struct sqButton : sqElem {
int x,y,sx,sy;
int pressed;
int shift;
sqButton(sqElem* _owner,int _x,int _y,int _sx,int _sy,int _shift = 1,int _pressed = 0);
virtual int* getXY(void){ return &x; }
virtual void draw(int self = 1);
virtual void handler(sqEvent* e);
};
struct sqTextButton : sqElem {
int x,y,sx,sy;
char* text;
sqFont* font;
int offset;
sqTextButton(sqElem* _owner,int _x,int _y,char* _text,sqFont* _font,int _sx = 0);
virtual int* getXY(void){ return &x; }
virtual void draw(int self = 1);
virtual void handler(sqEvent* e);
virtual void keytrap(int key);
virtual void activate(int force = 1);
virtual void deactivate(void);
virtual void remove(void);
};
struct sqInputString : sqElem {
int x,y;
int size,sy;
sqFont* font;
int len,clen;
int offset;
unsigned char* str,*savestr;
int index;
int blink;
int fstatus;
int type,dec;
static int insert,rus;
sqInputString(sqElem* _owner,int _x,int _y,int _size,sqFont* _font,unsigned char* _str = NULL,int _len = 0,int _type = T_STRING,int _dec = 0);
virtual ~sqInputString(void){ delete str; delete savestr; }
void delcursor(void);
void setstr(unsigned char* s);
char* getstr(void);
virtual int* getXY(void){ return &x; }
virtual void draw(int self = 1);
virtual void keytrap(int key);
virtual void quant(void);
virtual void handler(sqEvent* e);
virtual void activate(int force = 1);
virtual void deactivate(void);
};
struct sqField : sqInputString {
unsigned char* prompt;
int x0,y0;
sqField(sqElem* _owner,char* _prompt,int _x,int _y,int _size,sqFont* _font,unsigned char* _str = NULL,int _len = 0,int _type = T_STRING,int _dec = 0);
~sqField(void){ free(prompt); }
virtual void draw(int self = 1);
};
struct sqPopupMenu;
struct sqMenuBar {
unsigned char* data;
unsigned char* original_data;
sqMenuBar* next,*prev;
int status,value,rec;
sqMenuBar(unsigned char* s,sqPopupMenu* owner,int _status = 0,int _value = 0,int _rec = -1);
~sqMenuBar(void){ delete data; free(original_data); }
void replace(sqPopupMenu* owner,unsigned char* s);
};
struct sqPopupMenu : sqElem {
int x,y,sx,sy;
int visibars,maxbars;
sqMenuBar* first;
sqMenuBar* pointer;
sqMenuBar* insert;
int margin,len,len0;
int topbar,nbar;
sqFont* font;
unsigned char* seekbuf;
int seeklen;
unsigned int seekcounter;
sqPopupMenu(sqElem* _owner,int _x,int _y,int _visibars,sqFont* _font,int _len0 = 0,int _margin = 1);
virtual ~sqPopupMenu(void){ free(); delete seekbuf; }
sqPopupMenu& operator* (sqMenuBar* obj);
void disconnect(sqMenuBar* obj,sqMenuBar** del = NULL);
void setlen(int l);
sqMenuBar* getbar(int n);
int getptr(sqMenuBar* b);
void seek(sqMenuBar* p0,int force = 1);
void setpointer(sqMenuBar* p,int force = 1);
void free(void);
virtual int* getXY(void){ return &x; }
virtual void draw(int self = 1);
virtual void keytrap(int key);
virtual void handler(sqEvent* e);
virtual void activate(int force = 1);
virtual void deactivate(void);
};
struct sqMultiMenu : sqElem {
int x,y,sx,sy;
sqInputString* edit;
sqPopupMenu* list;
sqElem* obj;
int maxlen;
sqMenuBar* deleted;
sqMultiMenu(sqElem* _owner,int _x,int _y,int _visibars,sqFont* _font,int _maxlen);
virtual int* getXY(void){ return &x; }
virtual void keytrap(int key);
virtual void restore(int _x,int _y,int _sx,int _sy);
virtual void activate(int force = 1);
virtual void deactivate(void);
virtual void message(int code,sqElem* object = NULL);
};
struct sqFiler : sqElem {
int x,y,sx,sy;
sqInputString* skel;
sqPopupMenu* list;
unsigned int origindrive,max;
char* origindir;
unsigned int curdrive;
char* curdir;
sqElem* obj;
char* dirskel;
sqFiler(sqElem* _owner,int _x,int _y,int _visibars,sqFont* _font);
virtual ~sqFiler(void);
void build(void);
void setdirskel(void);
void choice(void);
virtual int* getXY(void){ return &x; }
virtual void keytrap(int key);
virtual void restore(int _x,int _y,int _sx,int _sy);
virtual void activate(int force = 1);
virtual void deactivate(void);
virtual void message(int code,sqElem* object = NULL);
};
struct sqInputBox : sqBox {
sqElem* obj;
char* title;
sqFont* font;
sqInputBox(sqElem* _owner,int _x,int _y,int _sx,int _sy,sqFont* _font,char* _title = NULL);
void close(void);
virtual void draw(int self = 1);
virtual void restore(int _x,int _y,int _sx,int _sy);
virtual void keytrap(int key);
virtual void message(int code,sqElem* object = NULL);
};
struct sqString {
unsigned char* data;
sqString* next,*prev;
sqString(unsigned char* s,int len);
~sqString(void){ if(data) delete data; }
};
struct sqText : sqElem {
int x,y,sx,sy;
int visistr;
sqString* first;
sqString* top;
sqString* last;
int len;
sqFont* font;
sqText(sqElem* _owner,int _x,int _y,int _visistr,sqFont* _font,int _len,unsigned char* buf,int maxbuf);
virtual ~sqText(void){ free(); }
sqText& operator* (sqString* obj);
void free(void);
void build(unsigned char* buf,int max);
int getptr(sqString* b);
sqString* getstr(int n);
virtual int* getXY(void){ return &x; }
virtual void draw(int self = 1);
virtual void keytrap(int key);
virtual void activate(int force = 1);
virtual void deactivate(void);
virtual void handler(sqEvent* e);
};
/* -------------------------- Prototypes & Externs -------------------------- */
extern int page;
extern sqEventQueue* sqE;
extern sqEventQueue* sqKey;
extern sqScreen* sqScr;
extern sqElem* QuantObj;
extern sqElem* KeyTrapObj;
void sqInit(int col0);
void sqInitMouse(void);
void sqRestoreCursor(void);
void sqQuant(void);
void sqSetPalette(char* pal);
char* sqstrNcpy(char* dest,char* src,int len);
#endif

1352
surmap/surmap.cpp Normal file

File diff suppressed because it is too large Load Diff

1307
surmap/tools.cpp Normal file

File diff suppressed because it is too large Load Diff

34
surmap/tools.h Normal file
View File

@@ -0,0 +1,34 @@
extern int MosaicTypes[8];
struct BitMap {
ushort sx,sy;
int sz;
uchar* data;
uchar* palette;
int force,mode,border,copt;
int mosaic;
int size,level;
int xoffset,yoffset;
BitMap(int _mosaic = 0);
void load(char* name);
void convert(void);
void place(char* name,int _force,int _mode,int _border = 0,int _level = 0,int _size = 0);
inline int getDelta(int x,int y,int delta){
x += xoffset;
y += yoffset;
if(!mode) return delta*(64 - data[(y%sy)*sx + (x%sx)])/64;
return delta + force*(64 - data[(y%sy)*sx + (x%sx)])/64;
}
inline int getType(int x,int y){
x += xoffset;
y += yoffset;
return MosaicTypes[data[(y%sy)*sx + (x%sx)]%8];
}
};
extern BitMap placeBMP;
extern BitMap mosaicBMP;
extern int curBmpIndex;

3527
surmap/track.cpp Normal file

File diff suppressed because it is too large Load Diff

231
surmap/track.h Normal file
View File

@@ -0,0 +1,231 @@
const int MOVING_SECTION = 2;
const int MOVING_NODE = 3;
const int SET_WIDE = 4;
const int SET_HEIGHT = 5;
const int SET_HEIGHT_NODE = 6;
const int BUILDING = 1;
const int WAIT = 0;
const int MAX_BRANCH = 8;
const int MAX_BASE = 64;
#ifdef __ZORTECHC__
const int MAX_ALL = 1024;
#else
const int MAX_ALL = 32*1024;
#endif
extern int min_len;
extern int MIN_WIDE;
extern int H_MAIN;
extern int WATERLINE;
extern int ROAD_MATERIAL;
extern int ROAD_FORCING;
const int COLOR_TRACK = 255;
const int COLOR_NODE = 100;
struct eNode;
struct Vec {
double x, y, h;
};
struct VectorT {
int x, y, h;
};
struct gLine {
int a, b;
int x, y;
};
struct eSection {
int x, y, h;
int xl, yl, hl;
int xr, yr, hr;
int wide;
int noise;
int dnoise;
int profil;
int dprofil;
int point;
int mode;
};
struct rSection {
int xl, yl, hl;
int xr, yr, hr;
};
struct eBranch{
int index;
int n_section;
int n_point;
int *xpb, *ypb;
int beg_node;
int *xpe, *ype;
int end_node;
int all_on;
int color;
int material;
int is_render;
eSection* data_base;
rSection* data_all;
eBranch* l;
eBranch* r;
eBranch* next;
int builded;
eBranch(void);
~eBranch(void);
void show(int);
void show_on_all(int,int,int,int);
int add_section( int, int, int );
int delete_point( int );
int find_point( int&, int&, int& );
int find_bound_point( int&, int, int );
int find_next_point_in_spline(int, int);
int insert_point( int, int );
void build_section(void);
void build_spline(void);
void set_section( int, int, int, int );
void set_wide_in_section( int , int, int );
void set_wide( int );
void rebuild_wide( void );
void render( int );
void render_full_section( int, int );
void save(XStream&);
void saveKron(XStream&);
void load(XStream&);
int linking(int stage);
};
struct eNode {
int index;
int x, y, h;
int *xp, *yp;
int polygon_on;
int noise;
int dnoise;
int color;
int material;
int mode;
int n_branch;
int* branches;
eNode* l;
eNode* r;
eNode* next;
int builded;
eNode(int, int, int);
~eNode(void);
int find_point( int&, int& );
void find_cross_point( eBranch*& ,int, int, int );
void add_branch( int );
void build_polygon( eBranch*&, int*&, int );
double get_alpha(eBranch*, int );
void show(void);
void show_on_all(int,int,int,int);
void render(int);
void save(XStream&);
void saveKron(eBranch*& branch, XStream&);
void load(XStream&);
int linking(int stage);
};
struct sTrack {
int n_node;
int n_branch;
eNode* node;
eBranch* branch;
eNode** nTails;
eBranch** bTails;
int linkingLog;
sTrack(void);
void curr_build(void);
void show(void);
void show_all_track(void);
void show_branch_height(int , int);
void show_node_height(int);
void build_all_branch(void);
void build_all_node(void);
void build_all_spline(void);
void render(int);
void set_noise_in_branch( int, int, int, int );
void set_wide_in_branch( int , int , int , int );
void set_point_in_branch( int, int, int, int, int );
void set_node( int, int, int, int );
void set_node_height( int, int );
void set_height_from_ground(int what);
void set_height_in_branch_from_ground( eBranch*, int cSection, int what );
void set_section_parametr( int , int , int , int, int, int, int, int, int, int, int, int, int, int );
void set_node_parametr( int, int, int, int, int, int, int, int);
void get_node_parametr( int, int&, int&, int&, int&, int&, int&);
void get_section_parametr( int, int, int&, int&, int&, int&, int&, int&, int&, int&, int&, int&, int&);
void delete_point_from_branch( int, int );
void delete_branch_from_node( int, int );
void delete_branch( int );
int delete_node( int );
int add_branch(int, int, int&, int);
int add_node(int, int, int);
int add_point_to_branch(int, int, int, int);
void add_branch_to_node( int, int );
int insert_point_in_branch( int, int );
int find_branch( int, int&, int&, int&, int& );
int find_node( int&, int&, int& );
int find_bound_point( int&, int&, int, int);
void concate_branch( int cwBranch, int cBranch );
int decompose_branch( int cwBranch, int cwPoint, int& cNode );
void prepare_branch_to_add_point( int cBranch, int cPoint );
void prepare_branch_concate( int cBranch, int cNode );
void lift_branch(int cBranch );
void recalc_height_branch(int cBranch );
void recalc_wide_branch(int cBranch, int new_wide );
int check_mouse_work(void);
void save(int);
void saveKron(int);
void load(int);
void linking(void);
};
typedef double (*PF)(double,double);
extern PF* profils;
extern sTrack Track;
extern int cPoint;
extern int cBranch;
extern int cwPoint;
extern int cwBranch;
extern int cNode;
extern int UcutLeft,UcutRight,VcutUp,VcutDown;

1425
surmap/world.cpp Normal file

File diff suppressed because it is too large Load Diff