nolibgs_hello_worlds/hello_2pads/hello_2pads.c

418 lines
11 KiB
C
Raw Normal View History

// 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;
}