SGL User's ManualPROGRAMMER'S STRUCT
BackForward
PROGRAMMER'S STRUCT

7. Polygon surface attributes


This chapter describes the surface attributes of polygons in Sega Saturn.
For polygons, "Sort" that indicates the reference position for determining the display order of each polygon, "front and back attributes" that specify whether to display one side or both sides of the polygon, and a two-dimensional picture for the polygon ( There is an element such as "texture" to paste (bitmap data).
These are collectively called "polygon surface attributes".
By specifying the surface attributes of polygons, you can add various expressions to polygons that were previously just pictures.

7-1. Attributes

In the Sega Graphic Library (SGL), the ATTRIBUTE macro is used to specify the surface attributes of polygons.
In the sample programs up to this chapter, the attributes have been set implicitly without explaining the contents of each parameter in detail.
However, attributes are a collection of important elements in dealing with polygons. Therefore, here we will explain in detail the meaning of each parameter of the ATTRIBUTE macro.

Listing 7-1 Attribute data
● Attribute data

ATTR attribute_label [] = { ATTRIBUTE (Plane, Sort, Texture, Color, Gouraund, Mode, Dir, Option), ................................... };

Note) The ATTRIBUTE macro is defined in “sl_def.h”.

The meaning of each parameter is as follows.

Plane: Indicates whether it is a single-sided polygon or a double-sided polygon (front and back attributes)
Sort: Shows the representative points of the positional relationship of polygons (Z sort)
Texture: Indicates the texture name (No.) Color: Indicates the color data Gouraud: Indicates the address of the Gouraud shading table Mode: Indicates the drawing mode of the polygon (various mode settings)
Dir: Indicates the state of polygons and textures Option: Indicates other functions (option setting)

7-2. Plane

The first parameter “Plane” of the attribute indicates the front and back attributes of the polygon. The front and back attributes are attributes that indicate whether the polygon is a single-sided polygon or a double-sided polygon.
Double-sided polygons can be seen from both the front and back, but single-sided polygons disappear when turned to the back.
The macros that can be specified for this parameter are introduced below.

Table 7-1 Plane (front and back attributes)
macro Contents
Single_Plane Single-sided display of polygons
Dual_Plane Double-sided display of polygons

Let's take a look at the sample program (Listing 7-2).
The single-sided yellow polygon rotates around the Y axis as a fulcrum.
Since it is a single-sided polygon, the back side is not displayed.

Listing 7-2 sample_7_2: main.c
/ * ------------------------------------------------ ---------------------- * /
/ * Rotation of Single Plane Polygon * /
/ * ------------------------------------------------ ---------------------- * /
#include "sgl.h"

extern PDATA PD_PLANE;

void ss_main (void)
{
	static ANGLE ang [XYZ];
	static FIXED pos [XYZ];

	slInitSystem (TV_320x224, NULL, 1);
	slPrint ("Sample program 7.2", slLocate (6,2));

	ang [X] = ang [Y] = ang [Z] = DEGtoANG (0.0);
	pos [X] = toFIXED (0.0);
	pos [Y] = toFIXED (0.0);
	pos [Z] = toFIXED (170.0);

	while (-1) {

		slPushMatrix ();
		{
			slTranslate (pos [X], pos [Y], pos [Z]);
			slRotX (ang [X]);
			slRotY (ang [Y]);
			slRotZ (ang [Z]);
			ang [Y] + = DEGtoANG (2.0);
			slPutPolygon (& PD_PLANE);
		}
		slPopMatrix ();

		slSynch ();
	}
}

Look at line 27. The polygon drawing routine “slPutPolygon” is called and a pointer to the polygon data “PD_PLANE” is passed.
“PD_PLANE” is defined in the source “polygon.c” as follows.

Listing 7-3 sample_7_2: Polygon.c
#include "sgl.h"

POINT point_PLANE [] = {
	POStoFIXED (-20.0, -20.0, 0.0),
	POStoFIXED (20.0, -20.0, 0.0),
	POStoFIXED (20.0, 20.0, 0.0),
	POStoFIXED (-20.0, 20.0, 0.0),
};

POLYGON polygon_PLANE [] = {
	NORMAL (0.0,0.0,1.0), VERTICES (0,1,2,3),
};

ATTR attribute_PLANE [] = {
	ATTRIBUTE (Single_Plane, SORT_CEN, No_Texture, C_RGB (31,31,0), No_Gouraud, MESHoff, sprPolygon, No_Option),
};

PDATA PD_PLANE = {
	point_PLANE, sizeof (point_PLANE) / sizeof (POINT),
	polygon_PLANE, sizeof (polygon_PLANE) / sizeof (POLYGON),
	attribute_PLANE
};

The 18th and subsequent lines are polygon data. The 21st line is a pointer to the attribute data, so the actual data starts from the 14th line.
You can see that the first parameter is “Single_Plane”.
<Rewrite this to “Dual_Plane” and execute it. Polygons that were previously displayed on only one side should now be displayed on both sides.

7-3. Sort

The second parameter "Sort" indicates the position of the Z sort on the polygon. Z-sort is a method that determines the position and context in 3D space based on the representative points on each polygon, and calculates and draws faster than the Z-buffer (determines the position for each pixel on the polygon) method. The feature is that it can be done. The macros that can be specified for this parameter are introduced below.

Table 7-2 Sort (Z sort specification)
macro Contents
SORT_MIN The vertex on the polygon closest to the camera is the representative point
SORT_CEN The center point of the polygon is the representative point
SORT_MAX The point farthest from the camera is the representative point
SORT_BFR Displayed in front of the polygon registered immediately before

In addition, this is shown in the figure below.

<Fig. 7-1 Representative points of Z sort>

“SORT_BFR” is a special specification and is used when you want to display one polygon above (front) another polygon. Specifically, the display position of the polygon for which "SORT_BFR" is specified is immediately before the polygon registered immediately before that polygon. However, since it is a specification that has meaning for the first time when you want to use two polygons as a group, you will not usually use it much.

Due to the nature of the Z sort method, there is a possibility that the context may become strange depending on how the representative points are taken. See the following example.

<Fig. 7-2 Differences in context depending on representative points>

If you specify a representative point as shown above, the actual screen will be as shown below.

<Fig. 7-3 Actual screen>

7-4. Texture

The third parameter "Texture" is the parameter required when using texture mapping. Here, specify the number of the texture to be actually used from the texture table registered by the function “slInitSystem”.
When not using a texture, specify the macro “No_Texture”. Texture mapping is a general term for the function of inserting two-dimensional graphics on the surface of polygons. Needless to say, polygons can only represent display colors, and their reality is limited. However, by making full use of the texture mapping function, it is possible to express more realistic 3D objects such as the texture of objects and surface patterns that could not be expressed by polygons alone.

Sega Saturn's texture mapping and so-called texture mapping in general CG have two different properties as shown in Table 7-3.

Table 7-3 Differences between Sega Saturn texture mapping and general CG texture mapping
Texture mapping
For Sega Saturn In the case of general CG
 Of texture
 Stake
It is possible to paste one texture for one polygon. You can paste a single texture across multiple polygons.
 Deformation
It also deforms the texture according to the shape of the polygon. The texture is clipped to the shape of the polygon.

● Paste texture

<Fig. 7-5 Texture features 1>

note)
There is a one-to-one correspondence between textures and polygons.

Textures in general CG can be pasted over multiple polygons, but in the case of Sega Saturn, one texture is pasted in correspondence with one polygon. When pasting a texture that spans two or more polygons, it is necessary to divide the texture according to each polygon as shown in Fig. 7-5.

● Texture deformation
For general CG textures, if the polygon is not a rectangle (including a square), the texture will be clipped in the shape of a polygon. However, in Sega Saturn, the texture deforms along the polygon without clipping. Even if the polygon is a triangle, the entire texture will be transformed into a triangle.

<Fig. 7-6 Texture feature 2>

note)
The texture is deformed according to the shape of the polygon.

About texture distortion

If the polygon is rectangular and the texture overlaid on it is square, the texture will be transformed into a rectangle to match the aspect ratio of the polygon. Therefore, keep in mind that the texture's aspect ratio should match the polygon's aspect ratio as much as possible to reduce texture distortion.

<Fig. 7-7 Texture distortion>

Let's take a look at the sample program (Listing 7-4).
A single textured polygon rotates around the Y axis as a fulcrum.
Here, register two textures in advance.
One is a [SONIC] picture (size: 64 x 64 pixels), and the other is an "AM2" mark (size: 64 x 32 pixels).

Listing 7-4 sample_7_4: main.c
/ * ------------------------------------------------ ---------------------- * /
/ * Polygon & Texture * /
/ * ------------------------------------------------ ---------------------- * /
#include "sgl.h"

extern PDATA PD_PLANE;
extern TEXTURE tex_sample [];
extern PICTURE pic_sample [];

#define max_texture 2

void set_texture (PICTURE * pcptr, Uint32 NbPicture)
{
	TEXTURE * txptr;
 
	for (; NbPicture-> 0; pcptr ++) {
		txptr = tex_sample + pcptr-> texno;
		slDMACopy ((void *) pcptr-> pcsrc,
			(void *) (SpriteVRAM + ((txptr-> CGadr) << 3)),
			(Uint32) ((txptr-> Hsize * txptr-> Vsize * 4) >> (pcptr-> cmode)));
	}
}

void ss_main (void)
{
	static ANGLE ang [XYZ];
	static FIXED pos [XYZ];

	slInitSystem (TV_320x224, tex_sample, 1);
	set_texture (pic_sample, max_texture);
	slPrint ("Sample program 7.4", slLocate (9,2));

	ang [X] = ang [Y] = ang [Z] = DEGtoANG (0.0);
	pos [X] = toFIXED (0.0);
	pos [Y] = toFIXED (0.0);
	pos [Z] = toFIXED (170.0);

	while (-1) {
		slPushMatrix ();
		{
			slTranslate (pos [X], pos [Y], pos [Z]);
			slRotX (ang [X]);
			slRotY (ang [Y]);
			slRotZ (ang [Z]);
			ang [Y] + = DEGtoANG (2.0);
			slPutPolygon (& PD_PLANE);
		}
		slPopMatrix ();

		slSynch ();
	}
}

The program flow itself is not much different from Listing 7-2.

First, pay attention to line 29.
This is the initialization routine that I used implicitly until now, but the second parameter is different. Here, specify the pointer to the texture table to be passed to SGL. (The actual table is defined in “texture.c”. See Listing 7-5 .) Since we didn't use textures before, we assigned “NULL”.

The 30th line transfers the texture data to V-RAM.
This texture data transfer can be performed at any time after initialization, so you can easily perform techniques such as redrawing textures during the game.

The 12th and subsequent lines are the actual texture data transfer routines.
Here, the start address of the texture table and the number of registered textures are received. Then, the “slDMACopy” function on the 18th line transfers data at high speed using DMA.
The first parameter of this function is the transfer source address, the second parameter is the transfer destination address, and the third parameter is the transfer size.

[Void slDMACopy (void * src, void * dst, Uint32 cnt);]
Data block transfer is performed using the DMA built into the CPU. Substitute the start address of the transfer source memory area, the start address of the transfer destination memory area, and the block transfer amount (unit: bytes) into the parameters.
The function terminates the transfer immediately after the DMA is activated.
If you want to know the transfer completion, use the function “slDMAWait”.

Next, let's look at the texture data.

Listing 7-5 sample_7_4: texture.c

#include "sgl.h"
/ ******************************** /
/ * Texture Data * /
/ ******************************** /

TEXDAT sonic_64x64 [] = {/ * Texture data 1 * /
	 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
					::
					::
				      Omission:
};

TEXDAT am2_64x32 [] = {/ * Texture data 2 * /
	 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
					::
					::
				      Omission:
};

TEXTURE tex_sample [] = {/ * Table to pass to SGL * /
	TEXDEF (64,64,0),
	TEXDEF (64,32,64 * 64 * 1),
};

PICTURE pic_sample [] = {/ * VRAM transfer table * /
	PICDEF (0, COL_32K, sonic_64x64),
	PICDEF (1, COL_32K, am2_64x32),
};

The part described by the TEXDAT macro is the actual texture data.
Although omitted in the above list, the source contains all the data. The format of the texture data is not mentioned here. See “Function Reference” in the Reference Manual.

The part described by the TEXTURE macro is the texture table to be passed to SGL.
Set the size of each texture (horizontal x vertical) and the offset value from the start address of the actual texture data.

Finally, the PICTURE macro part becomes the table for VRAM transfer.
Set the texture number, color mode, and pointer to the texture data, respectively.

Last but not least, let's take a look at the attributes of polygon data.

Listing 7-6 sample_7_4: polygon.c

#include "sgl.h"

#define PN_SONIC 0
#define PN_AM2 1

POINT point_plane [] = {
        POStoFIXED (-40.0, -40.0, 0.0),
        POStoFIXED (40.0, -40.0, 0.0),
        POStoFIXED (40.0, 40.0, 0.0),
        POStoFIXED (-40.0, 40.0, 0.0)
};

POLYGON polygon_plane [] = {
        NORMAL (0.0,0.0,1.0), VERTICES (0, 1, 2, 3)
};

ATTR attribute_plane [] = {
	ATTRIBUTE (Single_Plane, SORT_CEN, PN_SONIC, No_Palet, No_Gouraud, CL32KRGB | MESHoff, sprNoflip, No_Option),
};

PDATA PD_PLANE = {
        point_plane, sizeof (point_plane) / sizeof (POINT),
        polygon_plane, sizeof (polygon_plane) / sizeof (POLYGON),
        attribute_plane
};

The third parameter of "ATTRIBUTE" is "PN_SONIC".
In other words, "SONIC", which is the texture of registration number [0], is pasted on the polygon and displayed.
Also, try changing this parameter to “PN_AM2”.
This time the texture should change to the "AM2" mark with registration number [1].
Furthermore, by changing the first parameter "Single_Plane" to "Dual_Plane", it is possible to see the texture from the back side.

7-5. Color

The fourth parameter, "Color", specifies the offset address for the polygon color and texture color palette.
For polygons, the color data specification method is limited to RGB Direct. The format is “C_RGB (r, g, b)”. r, g, and b indicate the three primary colors of light, respectively, and are specified as decimal numbers from 0 to 31.
In the case of texture, the method of specifying color data depends on the specification in "Mode" (the sixth parameter of the attribute. See "7-7 Mode "). Specify the macro “No_Palet” in the 32768 color RGB mode, and specify the offset address to the color palette in the other index modes.

7-6. Gouraud

The fifth parameter “Gouraud” specifies the Gouraud table to be used for Gouraud shading. Gouraud shading is a term for flat shading in which the boundary between polygons is clear, and is a technique that makes the polygon surface look like a curved surface by applying shading processing and erasing the boundary between polygons. Sega Saturn uses the color gradation between the tops of polygons to achieve Gouraud shading.

<Fig. 7-8 Gouraud shading>
Flat shading Guro shading

Let's take a look at the sample program (Listing 7-7). A cube with Gouraud shading rotates around the Y axis as a fulcrum.

Listing 7-7 sample_7_6: main.c

/ * ------------------------------------------------ ---------------------- * /
/ * Gouraud Shading * /
/ * ------------------------------------------------ ---------------------- * /
#include "sgl.h"

extern PDATA PD_CUBE;

#define GRoffsetTBL (r, g, b) (((b & 0x1f) << 0) | ((g & 0x1f) << 5) | (r & 0x1f))
#define VRAMaddr (SpriteVRAM + 0x70000)

static Uint16 GRdata [6] [4] = {
	{GRoffsetTBL (0, -16, -16), GRoffsetTBL (0, -16, -16),
	  GRoffsetTBL (0, -16, -16), GRoffsetTBL (-16, 15, 0)}, 
	{GRoffsetTBL (0, -16, -16), GRoffsetTBL (0, -16, -16),
	  GRoffsetTBL (-16, 15, 0), GRoffsetTBL (0, -16, -16)}, 
	{GRoffsetTBL (-16, 15, 0), GRoffsetTBL (0, -16, -16),
	  GRoffsetTBL (0, -16, -16), GRoffsetTBL (0, -16, -16)}, 
	{GRoffsetTBL (0, -16, -16), GRoffsetTBL (-16, 15, 0),
	  GRoffsetTBL (0, -16, -16), GRoffsetTBL (0, -16, -16)}, 
	{GRoffsetTBL (0, -16, -16), GRoffsetTBL (-16, 15, 0),
	  GRoffsetTBL (0, -16, -16), GRoffsetTBL (0, -16, -16)}, 
	{GRoffsetTBL (-16, 15, 0), GRoffsetTBL (0, -16, -16), 
	  GRoffsetTBL (0, -16, -16), GRoffsetTBL (0, -16, -16)} 
};

void ss_main (void)
{
	static ANGLE ang [XYZ];
	static FIXED pos [XYZ];

	slInitSystem (TV_320x224, NULL, 1);
	slPrint ("Sample program 7.6", slLocate (9,2));

	ang [X] = DEGtoANG (30.0);
	ang [Y] = DEGtoANG (0.0);
	ang [Z] = DEGtoANG (0.0);
	pos [X] = toFIXED (0.0);
	pos [Y] = toFIXED (0.0);
	pos [Z] = toFIXED (200.0);

	slDMACopy (GRdata, (void *) VRAMaddr, sizeof (GRdata));

	while (-1) {
		slPushMatrix ();
		{
			slTranslate (pos [X], pos [Y], pos [Z]);
			slRotX (ang [X]);
			slRotY (ang [Y]);
			slRotZ (ang [Z]);
			slPutPolygon (& PD_CUBE);
		}
		slPopMatrix ();

		ang [Y] + = DEGtoANG (1.0);

		slSynch ();
	}
}

The routine itself for drawing and rotating a cube is not much different than the previous ones, so I won't explain it. The difference is in line 41, when the gourd table is being transferred to VRAM. The idea is the same as transferring texture data, and all the tables needed at the beginning are stored in VRAM.

Now let's look at the attributes.

Listing 7-8 sample_7_6: polygon.c

#include "sgl.h"

#define GRaddr 0xe000

static POINT point_CUBE [] = {
	POStoFIXED (-20.0, -20.0, 20.0),
	POStoFIXED (20.0, -20.0, 20.0),
	POStoFIXED (20.0, 20.0, 20.0),
	POStoFIXED (-20.0, 20.0, 20.0),
	POStoFIXED (-20.0, -20.0, -20.0),
	POStoFIXED (20.0, -20.0, -20.0),
	POStoFIXED (20.0, 20.0, -20.0),
	POStoFIXED (-20.0, 20.0, -20.0)
};

static POLYGON polygon_CUBE [] = {
	NORMAL (0.0, 0.0, 1.0), VERTICES (0, 1, 2, 3),
	NORMAL (-1.0, 0.0, 0.0), VERTICES (4, 0, 3, 7),
	NORMAL (0.0, 0.0, -1.0), VERTICES (5, 4, 7, 6),
	NORMAL (1.0, 0.0, 0.0), VERTICES (1, 5, 6, 2),
	NORMAL (0.0, -1.0, 0.0), VERTICES (4, 5, 1, 0),
	NORMAL (0.0, 1.0, 0.0), VERTICES (3, 2, 6, 7)
};

static ATTR attribute_CUBE [] = {
	ATTRIBUTE (Single_Plane, SORT_MIN, No_Texture, C_RGB (31,16,31), GRaddr, MESHoff | CL_Gouraud, sprPolygon, No_Option),
	ATTRIBUTE (Single_Plane, SORT_MIN, No_Texture, C_RGB (31,16,31), GRaddr + 1, MESHoff | CL_Gouraud, sprPolygon, No_Option),
	ATTRIBUTE (Single_Plane, SORT_MIN, No_Texture, C_RGB (31,16,31), GRaddr + 2, MESHoff | CL_Gouraud, sprPolygon, No_Option),
	ATTRIBUTE (Single_Plane, SORT_MIN, No_Texture, C_RGB (31,16,31), GRaddr + 3, MESHoff | CL_Gouraud, sprPolygon, No_Option),
	ATTRIBUTE (Single_Plane, SORT_MIN, No_Texture, C_RGB (31,16,31), GRaddr + 4, MESHoff | CL_Gouraud, sprPolygon, No_Option),
	ATTRIBUTE (Single_Plane, SORT_MIN, No_Texture, C_RGB (31,16,31), GRaddr + 5, MESHoff | CL_Gouraud, sprPolygon, No_Option),
};

PDATA PD_CUBE = {
	point_CUBE, sizeof (point_CUBE) / sizeof (POINT),
	polygon_CUBE, sizeof (polygon_CUBE) / sizeof (POLYGON),
	attribute_CUBE
};

Notice the attributes.
The VRAM address that stored the Gouraud data earlier is set in the 5th parameter “Gouraud”. The VRAM address here is (relative address ÷ 8).

Also pay attention to the sixth parameter “Mode”.
When using Gouraud shading, it is necessary to specify “CL_Gouraud” here. When not using Gouraud shading, specify the macro "No_Gouraud" for the 5th parameter, "Gouraud".

7-7. Mode

The sixth parameter is “Mode”.
Here you can add various conditions and settings to the polygon. The macros that can be specified here are as follows.

Table 7-4 Mode
group macro Contents
[1] No_Window Unrestricted by Window (default)
Window_In Display inside the Window
Window_Out Display outside the window
[2] MESHoff Normal display (default)
MESHon Display as a mesh
[3] ECdis Disable End Code
ECenb Enable End Code (default)
【Four】 SPdis Also show transparent pixels (default)
SPenb Do not show transparent pixels
【Five】 CL16Bnk 16 color bank mode (default)
CL16Look 16-color look-up table
CL64Bnk 64-color color bank mode
CL128Bnk 128 color color bank mode
CL256Bnk 256 color bank mode
CL32KRGB 32768 color RGB mode
[6] CL_Replace Overwrite (standard) mode (default)
CL_Shadow Shadow mode
CL_Half Semi-brightness mode
CL_Trans Semi-transparent mode
CL_Gouraud Gouraud shading mode
[7] HSSon Use high speed shrink
HSSoff Do not use high speed shrink (default)
[8] MSBon Set up MSB when writing to framebuffer
MSBoff Do not set MSB when writing to framebuffer (default)

You can specify one option for each group.
Use the or operator "|" to write continuously.
The omitted group is treated as if the default was specified.

caution
Not all groups can be abbreviated. If you want to make everything the default, specify "No_Window" as a dummy.

Group [5] is for specifying the color mode of the texture, so if you do not use the texture, be sure to set it to the default (“CL_16Bnk” or not specified). If you specify any other mode here, the polygons will not be displayed.

As an exception to group [6], “CL_Gouraud | -CL_Half” and “CL_Gouraud | -CL_Trans” can be used. Please use it when you want to use semi-brightness Gouraud shading and semi-transparent Gouraud shading.
When using Gouraud shading, it is necessary to set “CL_Gouraud” here as well as setting the 5th parameter.
When using semi-brightness, translucency, and Gouraud shading, polygons are only supported in RGB direct mode and textures are only supported in 32768 color RGB mode. Please note that it cannot be displayed correctly with other settings.

7-8. Dir

The seventh parameter is “Dir”. Specifies whether the object is a polygon or a texture, and if it is a texture, how to invert it.

Table 7-5 Dir
macro Contents
sprNoflip Display textures normally
sprHflip Flip the texture left and right
sprVflip Flip the texture upside down
sprHVflip Flip the texture up / down / left / right
sprPolygon Show polygons
sprPolyLine Show polyline
sprLine Display a straight line using the first two points

caution
Do not specify “sprHflip” or “sprVflip” unless you are using a texture for the object.
Specify “sprLine” as 4 points like other polygons (repeat the first 2 points).

7-9. Option

The last parameter is “Option”. Other settings for polygons and textures are specified here. The following five options are supported by the current SGL (Ver 3.0).

Table 7-6 Option
macro Contents
UseLight Perform light source calculation
UsePalette Indicates that the polygon color is in palette format
UseNearClip 4 Do not display when the vertices go out of the screen specified by slWindowClipLevel
UseDepth Calculate depth skew with parallel light sources
Use Gouraud Calculate light source with real-time goo (valid only for slPutPolygonX)

Multiple of these options can be specified using the or operator “|”.

caution
If you do not want to use the option, specify the macro “No_Option”.
If you want to calculate the light source when the polygon color is in palette format, use "UsePalette" and "UseLight" together.

Appendix SGL library functions introduced in this chapter

In this chapter, the functions in the following table are explained.

Table 7-7 SGL library functions introduced in this chapter
Functional type Function name Parameters function
void slDMACopy Src, dst, cnt Block transfer using CPU DMA


BackForward
SGL User's ManualPROGRAMMER'S STRUCT
Copyright SEGA ENTERPRISES, LTD., 1997