Japanese
SGL User's ManualPROGRAMMER'S TUTORIAL
BackForward
PROGRAMMER'S TUTORIAL

9.Controller input


In this chapter, we will explain the recognition method and actual operation of Sega Saturn's data input device using Sega Saturn's representative input device, Sega Saturn PAD.
The Sega Saturn PAD has four direction keys, ABCXYZ buttons, LR button and start button on the top of the controller as input devices.
We will explain how the data input using each input device of these controllers is judged inside the Sega Saturn, along with sample programs.

9-1. Input system used in Sega Saturn

The Sega Saturn can receive data from various data input devices connected to its input ports and reflect that data in programs.

The data input device mainly used on the Sega Saturn is the control PAD that comes with the main unit, called the Sega Saturn PAD.
Sega Saturn PAD is an input device consisting of direction keys, start button, ABC button, XYZ button, and LR button arranged to point in four directions.

Figure 9-1 Example of input device (Sega Saturn PAD)

●For Sega Saturn PAD, the following data can be entered.

In addition to the Sega Saturn PAD, the Sega Saturn also supports the input devices listed in Table 9-1.
However, please note that some of the devices included in this table are not currently available for sale (although they are planned to be released in the future).

Table 9-1 List of input devices
 Attribute
 Name
 Input configuration
      remarks
Digital Sega Saturn PAD Directional key, start, 8 button Sega Saturn standard pad
sega saturn mouse XY movement amount, start, 3 buttons The amount of mouse movement is stored as an absolute value.
megadora 3 button pad Directional key, start, 3 button Can be connected with Sega Tap
megadora 6 button pad Directional key, start, 6 button Can be connected with Sega Tap
analog analog joystick
(Mission Stick)
Direction lever, start, 8 buttons The amount of movement is the absolute value of the unsigned A/D output.
Special sega saturn keyboard Compatible with IBM keyboards
Auxiliary equipment Sega Saturn 6P Multitap Number of connections: 6
sega tap Number of connections 4 Used to connect Megadora PAD
Note) For details on each input device, refer to “HARDWARE MANUAL/ SMPC User's Manual ”.

9-2. Actual operation

The input device connected to the input port will send a signal to the Sega Saturn when the device's input device (direction keys, buttons, etc.) is turned on.
The Sega Sega Saturn receives this signal and changes the device bits provided in the system, and by reading these changes, the programmer can read the status of the input device.
Therefore, in this chapter, we will explain the actual operation using the Sega Saturn PAD, which is a typical input device for Sega Saturn.

Bits used for input system

Devices connected to input ports (Sega Saturn PAD, etc.) are recognized by the system, and a certain amount of space is reserved in the system for each device.
This area includes the peripheral ID (8 bits), which is a bit string for device type recognition (specific to each device), and the input status bit string that follows.
The input status bit string consists of 1 data string of 8 bits, and the data strings necessary for the connected device are prepared.
The bit value of the input status bit string remains 1 when there is no input, and changes to 0 only when there is input (while the key or button is pressed).

Sega Saturn PAD is processed as a set of bits as shown below.

Table 9-2 Sega Saturn PAD peripheral data format
bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
Peripheral ID 0 0 0 0 0 0 1 0
1st DATA Start A C B
2nd DATA R X Y Z L 1 1 1
Note: The last 3 bits of 2nd DATA are unused and are set to 1 for convenience.

reference:
For information on peripheral data formats for input devices other than Sega Saturn PAD,
"HARDWARE MANUAL"/"SMPC User's Manual" ■3.3 Supported peripheral data formats
Please refer to.

About storing data formats

The bit string representing the state of each device is automatically stored in the area specified by the system.

What is a peripheral?

Peripheral is a general term for all peripheral devices such as input/output, and peripheral ID is an ID for identifying peripheral devices.

Bit operation by input

Information about devices connected to input ports is secured in the system area as a collection of peripheral IDs followed by data strings (indicating the input status of the device).
Thereafter, changes in the state of the device are expressed as changes in the state of the specified area, and the programmer can receive information from the input device simply by checking the state of this area.

Figure 9-2 extracts only the pure device status information excluding the peripheral ID part from the Sega Saturn PAD device information and expands it into a 16-bit data string (data output by SGL as peripheral data). (also developed into this type).
Also, for devices other than Sega Saturn PAD, only this part is used for actual device processing (however, the data length varies depending on the device).
The input status bits are all 1 when there is no input, and the bits corresponding to the input device change to 0 only when there is input (while the key or button is pressed).

Figure 9-2 Sega Saturn PAD input status bit array (16bit display)

Figure 9-3 shows the change in the status bit string (16 bits) in the Sega Saturn PAD when there is no input at all, and then there are sequential inputs.

Figure 9-3 Changes in input status bit string (Sega Saturn PAD)

Handling of device information in SGL

In the case of SGL, information on the Sega Saturn PAD connected to the input port is stored in the system variable “Smpc_Peripheral[n]” (n=0 to 29).

The total number of devices currently connected to input port 1 and input port 2 is stored in the system variables “Per_Connect1” and “Per_Connect2”.
Also, if a multi-tap is connected, device information is stored in the “Smpc_Peripheral[n]” (n=0 to 14, 15 to 29) area.

The system variable "Smpc_Peripheral[ ]" stores a system-defined PerDigital type structure, and each member of the structure contains information as shown in the figure below.

Figure 9-4 “PerDigital” structure definition
● Definition contents of PerDigital structure ●

typedef struct{ /* digital device */
	Uint8 id; /* Peripheral ID */
	Uint16 data; /* Current peripheral data */
	Uint16 push /* Data of the pressed switch */
	Uint16 pull /* Released switch data */
}PerDigital;

Note) The above structure is defined in the header file “sl_def.h” that comes with the system.

data: 16-bit peripheral data (indicates the current bit state)
push: 16-bit peripheral data (bits change only at the moment the input is executed)
pull: 16-bit peripheral data (bits change only at the moment the input is released)
id: 8-bit data string indicating the device peripheral ID

Peripheral data is a set of bits that represent only the input state, excluding the peripheral ID from the data set described above, and in the case of Sega Saturn PAD, it is represented by expanding the input state bits into a 16-bit length. .

About peripheral data output

The members of the structure representing data for the Sega Saturn PAD introduced here consist only of the peripheral ID (8 bits) and input device switch ON/OFF information (16 bits), but for devices other than the Sega Saturn PAD, Corresponding structures are not necessarily the same.
For example, in the case of the Sega Saturn mouse, which is a pointing device, peripheral data holds the X and Y coordinates of the mouse pointer, in addition to the ON/OFF switch (16 bit) as a digital device. However, since the size of the structure is the same for all devices, it is also possible to refer to Sega Saturn mouse data as the Sega Saturn PAD type.

Note
For details on peripherals, please refer to “HARDWEAR MANUAL vol.1” and the header file “sl_def.h” included with the system.

Determining input data

The input information from the device is determined by comparing the peripheral data described above with the assignment data described next.
Assignment data is defined in the header file "sl_def.h" that comes with the system. For example, the assignments corresponding to each input device of the Sega Saturn PAD are defined as shown in the figure below.

Figure 9-5 #define value of assignment data (Sega Saturn PAD)
● Pat assignment ●
#define PER_DGT_KR (1<< 15) /* Direction key (→) */
#define PER_DGT_KL (1<< 14) /* Direction key (←) */
#define PER_DGT_KD (1<< 13) /* Direction key (↓) */
#define PER_DGT_KU (1<< 12) /* Direction key (↑) */
#define PER_DGT_ST (1<< 11) /* Start button */
#define PER_DGT_TA (1<< 10) /* A button */
#define PER_DGT_TC (1<< 9) /* C button */
#define PER_DGT_TB (1<< 8) /* B button */
#define PER_DGT_TR (1<< 7) /* R trigger */
#define PER_DGT_TX (1<< 6) /* X button */
#define PER_DGT_TY (1<< 5) /* Y button */
#define PER_DGT_TZ (1<< 4) /* Z button */
#define PER_DGT_TL (1<< 3) /* L trigger */

These assignments are used to check with peripheral data, so they correspond to the peripheral data length of each device. For example, the assignment for the A button on the Sega Saturn PAD is expanded as shown in the following figure (16 bit length). Also, in the assignment data, the bit corresponding to the input device to be determined is set to 1, and the other bits are set to 0.

Figure 9-6 Pad assignment contents (for PER_DGT_TA)

Note: Only the bit of the same order (10th bit) that operates when the A button is input is set to 1.

In the case of the Sega Saturn PAD, the input device consists of a simple ON/OFF switch, so the switch status can be checked by logical operation of the assignment data and peripheral data.

Figure 9-7 is an example of checking the input status by ANDing peripheral data and assignment data. If the input device specified by the assignment data is ON, 0 will be output as the calculation result.

This method is also used in the sample program, and it is designed to display sprites on the screen if the input device pointed to by the pad assignment is in the ON state.

Figure 9-7 Checking input status using assignment data

Also, here we performed data matching using an AND operation between the peripheral data and the assignment data, but of course it is not necessary to use this method.

9-3. Sample program

The sample program (Listing 9-1) was created to test controller input.
The program displays a graphic imitating a Sega Saturn PAD on the screen, and when there is a controller input, an instruction mark (finger shape) is displayed on the button at the position corresponding to the controller input.
This program also uses sprites for instruction marks, etc.

Listing 9-1 sample_9_1: Input test (main.c)


/*------------------------------------------------ ----------------------*/
/* Pad Control */
/*------------------------------------------------ ----------------------*/
#include "sgl.h"
#include "sega_sys.h"

#define NBG1_CEL_ADR ( VDP2_VRAM_B1 + 0x02000 )
#define NBG1_MAP_ADR ( VDP2_VRAM_B1 + 0x12000 )
#define NBG1_COL_ADR ( VDP2_COLRAM + 0x00200 )
#define BACK_COL_ADR ( VDP2_VRAM_A1 + 0x1fffe )
#define PAD_NUM 13

static Uint16 pad_asign[] = {
	PER_DGT_KU,
	PER_DGT_KD,
	PER_DGT_KR,
	PER_DGT_KL,
	PER_DGT_TA,
	PER_DGT_TB,
	PER_DGT_TC,
	PER_DGT_ST,
	PER_DGT_TX,
	PER_DGT_TY,
	PER_DGT_TZ,
	PER_DGT_TR,
	PER_DGT_TL,
};

extern pad_cel[];
extern pad_map[];
extern pad_pal[];
extern TEXTURE tex_spr[];
extern PICTURE pic_spr[];
extern FIXED stat[][XYZS];
extern SPR_ATTR attr[];
extern ANGLE angz[];

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

static void disp_sprite()
{
	static Sint32 i;
	Uint16 data;

	if(!Per_Connect1) return;
	data = Smpc_Peripheral[0].data;

	for(i=0;i< PAD_NUM;i++){
		if((data & pad_asign[i])==0){
			slDispSprite((FIXED *)stat[i],
				(SPR_ATTR *)(&attr[i].texno),(ANGLE)angz[i]);
		}
	}
}

void ss_main(void)
{
	slInitSystem(TV_320x224,tex_spr,1);
	slTVOff();
	set_sprite(pic_spr,1);
	slPrint("Sample program 9.1" , slLocate(9,2));
	
	slColRAMMode(CRM16_1024);
	slBack1ColSet((void *)BACK_COL_ADR , 0);

	slCharNbg1(COL_TYPE_256 , CHAR_SIZE_1x1);
	slPageNbg1((void *)NBG1_CEL_ADR , 0 , PNB_1WORD|CN_12BIT);
	slPlaneNbg1(PL_SIZE_1x1);
	slMapNbg1((void *)NBG1_MAP_ADR , (void *)NBG1_MAP_ADR , (void *)NBG1_MAP_ADR , (void *)NBG1_MAP_ADR);
	Cel2VRAM(pad_cel , (void *)NBG1_CEL_ADR , 483*64);
	Map2VRAM(pad_map, (void *)NBG1_MAP_ADR, 32, 19, 1, 256);
	Pal2CRAM(pad_pal , (void *)NBG1_COL_ADR , 256);

	slScrPosNbg1(toFIXED(-32.0) , toFIXED(-36.0));
	slScrAutoDisp(NBG0ON | NBG1ON);
	slTVOn();
	
	while(1) {
		disp_sprite();
		slSynch();
	} 
}

9-4. Library functions used in the sample

Here, we will briefly introduce some of the library functions used in the sample program that were not explained in the previous chapters and are considered to be particularly important. At the same time, we will also introduce some functions related to these functions.

sprite function

This is a function to display sprites.
Unlike scrolling, sprites are a type of graphic data used when you want to freely move and display multiple objects in smaller units.
Sprites are often used for moving characters in games that use 2D graphics.

[void slDispSprite ( FIXED *pos , ATTR *atrb , ANGLE Zrot );]
Display the sprite on the screen by specifying the position, scale, and display angle.
Assign the pointer to the 4-dimensional array FIXED type variable that represents the XYZ coordinate values and scale value, the start address of the area where sprite data is stored, and the display angle to the parameters.
Similar to the library function “slPutPolygon”, it also performs sorting by Z value, but it is not affected by the current matrix at all.
Also, if a negative value is assigned to the scale value, the scale is calculated based on the Z position and then multiplied by the complement of the parameter scale value to create the display scale.
For example, if you specify -2.0 for the scale value and there is a sprite in a position that would be displayed at 0.5 times the scale, it will actually be displayed at 1.0 times the scale.

[void slPutSprite ( FIXED *pos , ATTR *atrb , ANGLE Zrot );]
Calculates the position using the current matrix and displays the sprite on the screen scaled according to the perspective transformation. Assign the pointer to the 4-dimensional array FIXED type variable that represents the XYZ coordinate values and scale value, the start address of the area where sprite data is stored, and the display angle to the parameters. Similar to “slDispSprite”, the sprite will be scaled by the specified scale value, but if you assign a negative value, the sprite will be displayed upside down and horizontally flipped on the screen.

[void slSetSprite ( SPRITE *parms , FIXED Zpos ) ;]
Set the sprite control command data to be passed to the hardware in the transfer list. Assign the start address and Z coordinate position of the area where sprite data is stored to the parameters. This function is used when you want to create deformed sprites that cannot be created using library functions, or when you want to set a window that only affects a specific sprite.

Other functions

The two functions introduced here are both related to DMA transfer.
In the sample program, the function "slDMACopy" is used to transfer picture data for sprites (data transfer from the picture data storage area to the character generator area).

[void slDMACopy ( void *src , void *dst , Uint32 cnt ) ;]
It uses the CPU's built-in DMA to perform block transfers of data.
Assign 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) to the parameters.
This function ends the transfer immediately after starting the DMA, so if you want to know when the transfer is complete, use "slDMAWait".

[void slDMAWait ( void );]
Wait for the DMA transfer started with “slDMACopy” to complete.
“slDMACopy” always transfers data using the same channel, but if you use this function, if the previous DMA transfer is in progress, it will wait for the transfer to finish, and then start the next data transfer after the transfer is finished. It will be started.

[void slDMAXCopy ( void *src , void *dst , Uint32 cnt , Uint16 mode ) ;]
This allows you to specify how the pointer of the library function "slDMACopy" is moved. Assign the transfer start address of the transfer source memory area, block transfer amount (unit: bytes), and transfer mode flag to the parameters. The transfer mode flag specifies what to do with the address of the transfer source memory area, what to do with the address of the transfer destination memory area, and what to do with the transfer unit. The specification method is as follows.

Figure 9-8 Parameter substitution value (mode) for “slDMAXCopy”
Forwarding destination
increment Decrement fixed
Rotation
Sending
Former
increment Sinc_Dinc_Byte Sinc_Ddec_Byte Sinc_Dfix_Byte
Decrement Sdec_Dinc_Byte Ban Sdec_Dfix_Byte
fixed Sfix_Dinc_Byte Sfix_Ddec_Byte Ban
Note) The above values are defined in "sl_def.h".
Note) The above values are when the transfer unit is "Byte" . "Word" and "Long" can be specified as other transfer units.

Additional notes: SGL library functions that appeared in this chapter

In this chapter, we explained the functions in the table below.

Table 9-3 Library functions introduced in this chapter
 functional type
 Function name
 Parameter
         function
void slDispSprite FIXED *pos,ATTR *atrb,ANGLE Zrot Sprite display by specifying position, scale, and display angle
void slPutSprite FIXED *pos,ATTR *atrb,ANGLE Zrot Sprite display according to perspective transformation
void slSetSprite SPRITE *parms,FIXED Zpos Set in the buffer for transferring sprite data to hardware
void slDMACopy void *src,void *dst,Uint32 cnt DMA transfer of only C from A to B (same bus transfer possible)
void slDMAWait void Wait until DMA transfer is completed
void slDMAXCopy void *src,void *dst,Uint32 cnt,Uint16 mode DMA transfer from A to B with C only in transfer mode D (same bus transfer possible)


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