418 lines
11 KiB
C
418 lines
11 KiB
C
|
// hello_libpad example
|
|||
|
//
|
|||
|
// We're using libpad this time.
|
|||
|
// You can use the classic controller, analog, wheel, gun buttons or mouse
|
|||
|
//
|
|||
|
// Schnappy - 12/2020
|
|||
|
//
|
|||
|
// Based on : ../psyq/addons/scea/CNTRL/PAD.C
|
|||
|
//
|
|||
|
// Controller demo
|
|||
|
// Written by Mike Fulton
|
|||
|
// Last Modified 6:25pm, 11/15/96
|
|||
|
// Copyright (c) 1996 Sony Computer Entertainment America
|
|||
|
|
|||
|
|
|||
|
#include <sys/types.h>
|
|||
|
#include <stdio.h>
|
|||
|
#include <libgte.h>
|
|||
|
#include <libetc.h>
|
|||
|
#include <libgpu.h>
|
|||
|
#include <libapi.h>
|
|||
|
|
|||
|
#define VMODE 0 // Video Mode : 0 : NTSC, 1: PAL
|
|||
|
|
|||
|
#define SCREENXRES 320
|
|||
|
#define SCREENYRES 240
|
|||
|
|
|||
|
#define CENTERX SCREENXRES/2
|
|||
|
#define CENTERY SCREENYRES/2
|
|||
|
|
|||
|
#define MARGINX 32 // margins for text display
|
|||
|
#define MARGINY 32
|
|||
|
|
|||
|
#define FONTSIZE 8 * 7 // Text Field Height
|
|||
|
|
|||
|
#define OTLEN 8 // Ordering Table Length
|
|||
|
|
|||
|
DISPENV disp[2]; // Double buffered DISPENV and DRAWENV
|
|||
|
DRAWENV draw[2];
|
|||
|
|
|||
|
u_long ot[2][OTLEN]; // double ordering table of length 8 * 32 = 256 bits / 32 bytes
|
|||
|
|
|||
|
char primbuff[2][32768] = {1}; // double primitive buffer of length 32768 * 8 = 262.144 bits / 32,768 Kbytes
|
|||
|
|
|||
|
char *nextpri = primbuff[0]; // pointer to the next primitive in primbuff. Initially, points to the first bit of primbuff[0]
|
|||
|
|
|||
|
short db = 0; // index of which buffer is used, values 0, 1
|
|||
|
|
|||
|
|
|||
|
// Pad stuff
|
|||
|
|
|||
|
// Structure for RAW hardware-based light gun position values
|
|||
|
|
|||
|
typedef struct
|
|||
|
{
|
|||
|
unsigned short v_count; // Y-axis (vertical scan counter)
|
|||
|
unsigned short h_count; // H-axis (horizontal pixel clock value)
|
|||
|
} Gun_Position;
|
|||
|
|
|||
|
// Structure for storing processed controller data
|
|||
|
|
|||
|
typedef struct
|
|||
|
{
|
|||
|
int xpos, ypos; // Stored position for sprite(s)
|
|||
|
int xpos2, ypos2; // controlled by this controller.
|
|||
|
|
|||
|
unsigned char status; // These 8 values are obtained
|
|||
|
unsigned char type; // directly from the controller
|
|||
|
unsigned char button1; // buffer we installed with InitPAD.
|
|||
|
unsigned char button2;
|
|||
|
unsigned char analog0;
|
|||
|
unsigned char analog1;
|
|||
|
unsigned char analog2;
|
|||
|
unsigned char analog3;
|
|||
|
} Controller_Data;
|
|||
|
|
|||
|
// All-purpose controller data buffer
|
|||
|
|
|||
|
typedef struct
|
|||
|
{
|
|||
|
unsigned char pad[34]; // 8-bytes w/o Multi-Tap, 34-bytes w/Multi-Tap
|
|||
|
} Controller_Buffer;
|
|||
|
|
|||
|
Controller_Buffer controllers[2]; // Buffers for reading controllers
|
|||
|
|
|||
|
Controller_Data theControllers[8]; // Processed controller data
|
|||
|
|
|||
|
void init(void)
|
|||
|
{
|
|||
|
ResetGraph(0);
|
|||
|
|
|||
|
SetDefDispEnv(&disp[0], 0, 0, SCREENXRES, SCREENYRES);
|
|||
|
SetDefDispEnv(&disp[1], 0, SCREENYRES, SCREENXRES, SCREENYRES);
|
|||
|
|
|||
|
SetDefDrawEnv(&draw[0], 0, SCREENYRES, SCREENXRES, SCREENYRES);
|
|||
|
SetDefDrawEnv(&draw[1], 0, 0, SCREENXRES, SCREENYRES);
|
|||
|
|
|||
|
if (VMODE)
|
|||
|
{
|
|||
|
SetVideoMode(MODE_PAL);
|
|||
|
disp[0].screen.y += 8;
|
|||
|
disp[1].screen.y += 8;
|
|||
|
}
|
|||
|
|
|||
|
setRGB0(&draw[0], 50, 50, 50);
|
|||
|
setRGB0(&draw[1], 50, 50, 50);
|
|||
|
|
|||
|
draw[0].isbg = 1;
|
|||
|
draw[1].isbg = 1;
|
|||
|
|
|||
|
PutDispEnv(&disp[db]);
|
|||
|
PutDrawEnv(&draw[db]);
|
|||
|
|
|||
|
FntLoad(960, 0);
|
|||
|
FntOpen(MARGINX, SCREENYRES - MARGINY - FONTSIZE, SCREENXRES - MARGINX * 2, FONTSIZE, 0, 280 );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
void display(void)
|
|||
|
{
|
|||
|
DrawSync(0);
|
|||
|
VSync(0);
|
|||
|
|
|||
|
PutDispEnv(&disp[db]);
|
|||
|
PutDrawEnv(&draw[db]);
|
|||
|
|
|||
|
SetDispMask(1);
|
|||
|
|
|||
|
DrawOTag(ot[db] + OTLEN - 1);
|
|||
|
|
|||
|
db = !db;
|
|||
|
|
|||
|
nextpri = primbuff[db];
|
|||
|
}
|
|||
|
|
|||
|
void get_digital_direction( Controller_Data *c, int buttondata ) // get analog stick values
|
|||
|
{
|
|||
|
int i;
|
|||
|
|
|||
|
i = ~(buttondata);
|
|||
|
|
|||
|
if( i & 0x80 )
|
|||
|
c->xpos -= 1;
|
|||
|
|
|||
|
if( i & 0x20 )
|
|||
|
c->xpos += 1;
|
|||
|
|
|||
|
if( i & 0x40 )
|
|||
|
c->ypos += 1;
|
|||
|
|
|||
|
if( i & 0x10 )
|
|||
|
c->ypos -= 1;
|
|||
|
}
|
|||
|
|
|||
|
void read_controller( Controller_Data *c, unsigned char *buf, int port ) // get the raw values from controller
|
|||
|
{
|
|||
|
register int mouse_x, mouse_y, x;
|
|||
|
register Gun_Position *g;
|
|||
|
|
|||
|
c->status = buf[0]; // Copy over raw controller data
|
|||
|
c->type = buf[1];
|
|||
|
c->button1 = buf[2];
|
|||
|
c->button2 = buf[3];
|
|||
|
c->analog0 = buf[4];
|
|||
|
c->analog1 = buf[5];
|
|||
|
c->analog2 = buf[6];
|
|||
|
c->analog3 = buf[7];
|
|||
|
|
|||
|
if( buf[0] == 0xff ) // If controller returns BAD status then bail on it.
|
|||
|
{
|
|||
|
c->type = 0;
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// Look at the controller type code & process controller data as indicated
|
|||
|
|
|||
|
switch( c->type )
|
|||
|
{
|
|||
|
case 0x12: // Sony Mouse
|
|||
|
mouse_x = buf[4];
|
|||
|
mouse_y = buf[5];
|
|||
|
|
|||
|
if( mouse_x & 0x80 )
|
|||
|
mouse_x |= 0xffffff80;
|
|||
|
if( mouse_y & 0x80 )
|
|||
|
mouse_y |= 0xffffff80;
|
|||
|
|
|||
|
c->xpos += mouse_x;
|
|||
|
c->ypos += mouse_y;
|
|||
|
break;
|
|||
|
|
|||
|
case 0x23: // Namco negCon
|
|||
|
// Steering wheel
|
|||
|
// Sankyo Pachinko controler
|
|||
|
get_digital_direction( c, buf[2] );
|
|||
|
break;
|
|||
|
|
|||
|
case 0x53: // Analog 2-stick
|
|||
|
get_digital_direction( c, buf[2] );
|
|||
|
break;
|
|||
|
|
|||
|
case 0x41: // Standard Sony PAD controller
|
|||
|
get_digital_direction( c, buf[2] );
|
|||
|
break;
|
|||
|
|
|||
|
default: // If don't know what it is, treat it like standard controller
|
|||
|
get_digital_direction( c, buf[2] );
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
int main(void)
|
|||
|
{
|
|||
|
|
|||
|
TILE * PADL; // Tile primitives
|
|||
|
TILE * TRIGGERL;
|
|||
|
|
|||
|
TILE * PADR;
|
|||
|
TILE * TRIGGERR;
|
|||
|
|
|||
|
TILE * START, * SELECT;
|
|||
|
|
|||
|
init();
|
|||
|
|
|||
|
InitPAD(controllers[0].pad, 34, controllers[1].pad, 34);
|
|||
|
|
|||
|
StartPAD();
|
|||
|
|
|||
|
|
|||
|
while (1)
|
|||
|
{
|
|||
|
|
|||
|
read_controller( &theControllers[0], &controllers[0].pad[0], 0 ); // Read controllers
|
|||
|
read_controller( &theControllers[1], &controllers[1].pad[0], 1 );
|
|||
|
|
|||
|
ClearOTagR(ot[db], OTLEN);
|
|||
|
|
|||
|
// D-cross
|
|||
|
|
|||
|
PADL = (TILE *)nextpri;
|
|||
|
|
|||
|
setTile(PADL);
|
|||
|
setRGB0(PADL, 80, 180, 255);
|
|||
|
setXY0(PADL, CENTERX - 80, CENTERY);
|
|||
|
setWH(PADL, 24, 24);
|
|||
|
|
|||
|
|
|||
|
addPrim(ot[db], PADL);
|
|||
|
|
|||
|
nextpri += sizeof(TILE);
|
|||
|
|
|||
|
// L1+L2
|
|||
|
|
|||
|
TRIGGERL = (TILE *)nextpri;
|
|||
|
|
|||
|
setTile(TRIGGERL);
|
|||
|
setRGB0(TRIGGERL, 255, 0, 0);
|
|||
|
setXY0(TRIGGERL, CENTERX - 80, CENTERY - 80);
|
|||
|
setWH(TRIGGERL, 24, 24);
|
|||
|
|
|||
|
|
|||
|
addPrim(ot[db], TRIGGERL);
|
|||
|
|
|||
|
nextpri += sizeof(TILE);
|
|||
|
|
|||
|
// /\, X, O, []
|
|||
|
|
|||
|
PADR = (TILE *)nextpri;
|
|||
|
|
|||
|
setTile(PADR);
|
|||
|
setRGB0(PADR, 0, 255, 0);
|
|||
|
setXY0(PADR, CENTERX + 50, CENTERY);
|
|||
|
setWH(PADR, 24, 24);
|
|||
|
|
|||
|
addPrim(ot[db], PADR);
|
|||
|
|
|||
|
nextpri += sizeof(TILE);
|
|||
|
|
|||
|
// R1+R2
|
|||
|
|
|||
|
TRIGGERR = (TILE *)nextpri;
|
|||
|
|
|||
|
setTile(TRIGGERR);
|
|||
|
setRGB0(TRIGGERR, 255, 0, 255);
|
|||
|
setXY0(TRIGGERR, CENTERX + 50, CENTERY -80);
|
|||
|
setWH(TRIGGERR, 24, 24);
|
|||
|
|
|||
|
addPrim(ot[db], TRIGGERR);
|
|||
|
|
|||
|
nextpri += sizeof(TILE);
|
|||
|
|
|||
|
// START + SELECT
|
|||
|
|
|||
|
START = (TILE *)nextpri;
|
|||
|
|
|||
|
setTile(START);
|
|||
|
setRGB0(START, 240, 240, 240);
|
|||
|
setXY0(START, CENTERX - 16, CENTERY - 36);
|
|||
|
setWH(START, 24, 24);
|
|||
|
|
|||
|
addPrim(ot[db], START);
|
|||
|
|
|||
|
nextpri += sizeof(TILE);
|
|||
|
|
|||
|
// D-pad
|
|||
|
|
|||
|
switch(theControllers[0].button1){
|
|||
|
|
|||
|
case 0xDF: // Right
|
|||
|
PADL->x0 = CENTERX - 64;
|
|||
|
break;
|
|||
|
case 0x7F: // Left
|
|||
|
PADL->x0 = CENTERX - 96;
|
|||
|
break;
|
|||
|
case 0xEF: // Up
|
|||
|
PADL->y0 = CENTERY - 16;
|
|||
|
break;
|
|||
|
case 0xBF: // Down
|
|||
|
PADL->y0 = CENTERY + 16;
|
|||
|
break;
|
|||
|
|
|||
|
// Start & Select
|
|||
|
|
|||
|
case 0xF7:
|
|||
|
START->w = 32; START->h = 32;START->x0 -= 4;START->y0 -= 4; // START
|
|||
|
break;
|
|||
|
case 0xFE: // SELECT
|
|||
|
START->r0 = 0;
|
|||
|
break;
|
|||
|
|
|||
|
// Dualshock L3 + R3
|
|||
|
|
|||
|
case 0xFD: // L3
|
|||
|
TRIGGERL->w += 10;
|
|||
|
TRIGGERL->h += 10;
|
|||
|
break;
|
|||
|
|
|||
|
case 0xFB: //R3
|
|||
|
TRIGGERR->w += 10;
|
|||
|
TRIGGERR->h += 10;
|
|||
|
break;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
// Buttons
|
|||
|
|
|||
|
switch(theControllers[0].button2){
|
|||
|
|
|||
|
case 0xDF: // ⭘
|
|||
|
PADR->x0 = CENTERX + 66;
|
|||
|
break;
|
|||
|
case 0x7F: // ⬜
|
|||
|
PADR->x0 = CENTERX + 34;
|
|||
|
break;
|
|||
|
case 0xEF: // △
|
|||
|
PADR->y0 = CENTERY - 16;
|
|||
|
break;
|
|||
|
case 0xBF: // ╳
|
|||
|
PADR->y0 = CENTERY + 16;
|
|||
|
break;
|
|||
|
|
|||
|
// Shoulder buttons
|
|||
|
|
|||
|
case 0xFB: // L1
|
|||
|
TRIGGERL->y0 = CENTERY - 64;
|
|||
|
break;
|
|||
|
case 0xFE: // L2
|
|||
|
TRIGGERL->y0 = CENTERY - 96;
|
|||
|
break;
|
|||
|
|
|||
|
case 0xF7: // R1
|
|||
|
TRIGGERR->y0 = CENTERY - 96;
|
|||
|
break;
|
|||
|
case 0xFD: // R2
|
|||
|
TRIGGERR->y0 = CENTERY - 64;
|
|||
|
break;
|
|||
|
|
|||
|
|
|||
|
// Mouse buttons
|
|||
|
|
|||
|
case 0xF4: // Mouse Left click
|
|||
|
PADL->w += 10;
|
|||
|
PADL->h += 10;
|
|||
|
break;
|
|||
|
|
|||
|
case 0xF8: // Mouse Right click
|
|||
|
PADL->w -= 10;
|
|||
|
PADL->h -= 10;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
FntPrint("Hello 2 pads!\n\n");
|
|||
|
|
|||
|
FntPrint( "Pad 1 : %02x\nButtons:%02x %02x, Stick:%02x %02x %02x %02x\n",
|
|||
|
theControllers[0].type, // Controller type : 00 == none, 41 == standard, 73 == analog/dualshock, 12 == mouse, 23 == steering wheel, 63 == gun, 53 == analog joystick
|
|||
|
theControllers[0].button1, //
|
|||
|
theControllers[0].button2,
|
|||
|
theControllers[0].analog0,
|
|||
|
theControllers[0].analog1,
|
|||
|
theControllers[0].analog2,
|
|||
|
theControllers[0].analog3 );
|
|||
|
|
|||
|
FntPrint( "Pad 2 : %02x\nButtons:%02x %02x, Stick:%02x %02x %02x %02x\n",
|
|||
|
theControllers[1].type, // Controller type : 00 == none, 41 == standard, 73 == analog/dualshock, 12 == mouse, 23 == steering wheel, 63 == gun, 53 == analog joystick
|
|||
|
theControllers[1].button1, //
|
|||
|
theControllers[1].button2,
|
|||
|
theControllers[1].analog0, // R3 horizontal
|
|||
|
theControllers[1].analog1, // R3 vertical
|
|||
|
theControllers[1].analog2, // L3 horizontal
|
|||
|
theControllers[1].analog3 ); // L3 vertical
|
|||
|
FntFlush(-1);
|
|||
|
|
|||
|
display();
|
|||
|
}
|
|||
|
return 0;
|
|||
|
}
|