singe/thirdparty/manymouse/example/mmpong.c
2023-10-23 19:38:18 -05:00

333 lines
7.2 KiB
C

/* MMPong - a Pong example using ManyMouse
Damon Ragno - with parts copied from the SDL manymouse example by Ryan Gordon
version 0.0.1
TODO:
-clean up the code, so it actually looks like something that would be an example
-add increasing speed
-add an actual scoreboard and not stdout
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "SDL.h"
#include "manymouse.h"
#define MAX_MICE 32
#define LEFT 0
#define RIGHT 1
#define UP 2
#define DOWN 3
int available_mice = 0;
typedef struct
{
int connected;
int x;
int y;
SDL_Color color;
char name[64];
} Mouse;
typedef struct
{
int x;
int y;
int speed;
int dir_h;
int dir_w;
} Ball;
static Mouse mice[MAX_MICE];
static Ball puck;
static int score1 = 0 , score2=0;
void score(int who)
{
const char *fmt = "MMPong, an example of ManyMouse usage: Score: %d - %d";
size_t len = sizeof (fmt) + 64;
char *buf = (char *) alloca(len);
Ball *ball = &puck;
if(who == 1){
score1++;
printf("player 1 has %d goals\n", score1);
} else{
score2++;
printf("player 2 has %d goals\n", score2);
}
snprintf(buf, len, fmt, score1, score2);
SDL_WM_SetCaption(buf, "MMPong");
ball->x = 320 ;
ball->y = rand() % 480 ;
ball->speed = 1;
if(rand() % 2 == 0) ball->dir_h = UP; else ball->dir_h = DOWN;
if(rand() % 2 == 0) ball->dir_w = LEFT; else ball->dir_w = RIGHT;
}
static void initial_setup(int screen_w, int screen_h)
{
int i;
memset(mice, '\0', sizeof (mice));
Ball *ball = &puck;
/* pick some random colors for each mouse. Sets position of both paddles */
for (i = 0; i < MAX_MICE; i++)
{
Mouse *mouse = &mice[i];
if((i % 2) == 0){
mouse->x = 2;
mouse->y = screen_h / 2;
} else {
mouse->x = screen_w -17 ;
mouse->y = screen_h / 2;
}
mouse->color.r = (int) (255.0*rand()/(RAND_MAX+1.0));
mouse->color.g = (int) (255.0*rand()/(RAND_MAX+1.0));
mouse->color.b = (int) (255.0*rand()/(RAND_MAX+1.0));
}
ball->x = screen_w / 2;
ball->y = rand() % screen_h;
ball->speed = 1;
ball->dir_h = UP;
ball->dir_w = LEFT;
}
static void init_mice(void)
{
int i;
available_mice = ManyMouse_Init();
if (available_mice < 0)
{
printf("Error initializing ManyMouse!\n");
return;
}
printf("ManyMouse driver: %s\n", ManyMouse_DriverName());
if (available_mice == 0)
{
printf("No mice detected!\n");
return;
}
for (i = 0; i < available_mice; i++)
{
const char *name = ManyMouse_DeviceName(i);
printf("#%d: %s\n", i, name);
}
if (available_mice > MAX_MICE)
{
printf("Clamping to first %d mice.\n", available_mice);
available_mice = MAX_MICE;
}
for (i = 0; i < available_mice; i++)
{
const char *name = ManyMouse_DeviceName(i);
strncpy(mice[i].name, name, sizeof (mice[i].name));
mice[i].name[sizeof (mice[i].name) - 1] = '\0';
mice[i].connected = 1;
}
}
static void update_mice(int screen_w, int screen_h)
{
ManyMouseEvent event;
while (ManyMouse_PollEvent(&event))
{
Mouse *mouse;
if (event.device >= (unsigned int) available_mice)
continue;
mouse = &mice[event.device];
if (event.type == MANYMOUSE_EVENT_RELMOTION)
{
/* ignore side to side mouse movement */
if (event.item == 1) mouse->y += event.value;
if (mouse->y < 0) mouse->y = 0;
if (mouse->y > 410) mouse->y = 410;
}
else if (event.type == MANYMOUSE_EVENT_ABSMOTION)
; /* !!! FIXME: do something with this. */
else if (event.type == MANYMOUSE_EVENT_BUTTON)
; /* !!! FIXME: do something with this. */
else if (event.type == MANYMOUSE_EVENT_SCROLL)
; /* !!! FIXME: do something with this. */
else if (event.type == MANYMOUSE_EVENT_DISCONNECT)
mice[event.device].connected = 0;
}
}
static void update_ball(int screen_w, int screen_h)
{
static Uint32 lastupdate = 0;
Uint32 now = SDL_GetTicks();
Ball *ball = &puck;
int i = 0;
if (now - lastupdate < 10)
return;
lastupdate += 10;
if(ball->y < 0) ball->dir_h = DOWN;
else if(ball->y > screen_h - 10) ball->dir_h = UP;
if(ball->x < 15){
int scored = 1;
for (i = 0; i < available_mice; i += 2) {
if((ball->y >= mice[i].y) && (ball->y < mice[i].y + 70)) {
scored = 0;
break;
}
}
if (scored)
score(2);
else
ball->dir_w = RIGHT;
}
else if(ball->x > (screen_w - 25)) {
int scored = 1;
for (i = 1; i < available_mice; i += 2) {
if((ball->y >= mice[i].y) && (ball->y < mice[i].y + 70)) {
scored = 0;
break;
}
}
if (scored)
score(1);
else
ball->dir_w = LEFT;
}
if(ball->dir_w == LEFT && ball->dir_h == UP){
ball->x -= 3 ;
ball->y -= 3 ;
}
if(ball->dir_w == RIGHT && ball->dir_h == UP){
ball->x += 3;
ball->y -= 3 ;
}
if(ball->dir_w == LEFT && ball->dir_h == DOWN){
ball->x -= 3;
ball->y += 3;
}
if(ball->dir_w == RIGHT && ball->dir_h == DOWN){
ball->x +=3;
ball->y += 3;
}
}
static void draw_mouse(SDL_Surface *screen, int idx)
{
SDL_Rect r = { mice[idx].x, mice[idx].y, 15, 70 };
Uint32 color;
if (!mice[idx].connected)
return;
if (mice[idx].x < 0) mice[idx].x = 0;
if (mice[idx].x >= screen->w) mice[idx].x = screen->w-1;
if (mice[idx].y < 0) mice[idx].y = 0;
if (mice[idx].y >= screen->h) mice[idx].y = screen->h-1;
color = SDL_MapRGB(screen->format, mice[idx].color.r,
mice[idx].color.g, mice[idx].color.b);
SDL_FillRect(screen, &r, color);
}
static void draw_screen(SDL_Surface *screen)
{
int i;
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 50, 0, 0));
for (i = 0; i < available_mice; i++)
draw_mouse(screen, i);
Ball *ball = &puck;
SDL_Rect b = {ball->x, ball->y, 10, 10};
Uint32 color = SDL_MapRGB(screen->format, 255, 255, 43);
SDL_FillRect(screen, &b, color);
SDL_Flip(screen);
}
int main(int argc, char *argv[])
{
Uint32 initflags = SDL_INIT_VIDEO; /* See documentation for details */
SDL_Surface *screen;
Uint8 video_bpp = 0;
Uint32 videoflags = (SDL_HWSURFACE || SDL_DOUBLEBUF);
int done;
int cursor = 0;
SDL_Event event;
/* Initialize the SDL library */
if ( SDL_Init(initflags) < 0 ) {
fprintf(stderr, "Couldn't initialize SDL: %s\n",
SDL_GetError());
exit(1);
}
/* Set 640x480 video mode */
screen=SDL_SetVideoMode(640,480, video_bpp, videoflags);
if (screen == NULL) {
fprintf(stderr, "Couldn't set 640x480x%d video mode: %s\n",
video_bpp, SDL_GetError());
SDL_Quit();
exit(2);
}
SDL_WM_SetCaption("MMPong, an example of ManyMouse usage: Score: 0 - 0", "MMPong");
SDL_ShowCursor(cursor);
SDL_WM_GrabInput(SDL_GRAB_ON);
initial_setup(screen->w, screen->h);
init_mice();
done = 0;
while ( !done ) {
/* Check for events */
while ( SDL_PollEvent(&event) ) {
switch (event.type) {
case SDL_MOUSEMOTION:
break;
case SDL_MOUSEBUTTONDOWN:
break;
case SDL_KEYDOWN:
/* Any keypress quits the app... */
case SDL_QUIT:
done = 1;
break;
default:
break;
}
}
update_mice(screen->w, screen->h);
update_ball(screen->w, screen->h);
draw_screen(screen);
}
/* Clean up the SDL library */
ManyMouse_Quit();
SDL_Quit();
return 0;
}