Add pong sample to samples/

This commit is contained in:
shinyquagsire23 2016-07-25 14:20:15 -07:00
parent f3b251baf3
commit bd39d9e294
9 changed files with 1134 additions and 0 deletions

70
samples/pong/Makefile Normal file
View File

@ -0,0 +1,70 @@
.SUFFIXES:
ifeq ($(strip $(WUT_ROOT)),)
$(error "Please ensure WUT_ROOT is in your environment.")
endif
ifeq ($(shell uname -o),Cygwin)
ROOT := $(shell cygpath -w ${CURDIR})
WUT_ROOT := $(shell cygpath -w ${WUT_ROOT})
else
ROOT := $(CURDIR)
endif
include $(WUT_ROOT)/rules/rpl.mk
TARGET := $(notdir $(CURDIR))
BUILD := build
SOURCE := src
INCLUDE := include
DATA := data
LIBS := -lgcc -lcrt -lcoreinit -lvpad -lsysapp
CFLAGS += -O2 -Wall -std=c11
CXXFLAGS += -O2 -Wall
ASFLAGS += -mregnames
ifneq ($(BUILD),$(notdir $(CURDIR)))
export OUTPUT := $(ROOT)/$(TARGET)
export VPATH := $(foreach dir,$(SOURCE),$(ROOT)/$(dir)) \
$(foreach dir,$(DATA),$(ROOT)/$(dir))
export BUILDDIR := $(ROOT)
export DEPSDIR := $(BUILDDIR)
CFILES := $(foreach dir,$(SOURCE),$(notdir $(wildcard $(dir)/*.c)))
CXXFILES := $(foreach dir,$(SOURCE),$(notdir $(wildcard $(dir)/*.cpp)))
SFILES := $(foreach dir,$(SOURCE),$(notdir $(wildcard $(dir)/*.S)))
ifeq ($(strip $(CXXFILES)),)
export LD := $(CC)
else
export LD := $(CXX)
endif
export OFILES := $(CFILES:.c=.o) \
$(CXXFILES:.cpp=.o) \
$(SFILES:.S=.o)
export INCLUDES := $(foreach dir,$(INCLUDE),-I$(ROOT)/$(dir)) \
-I$(ROOT)/$(BUILD)
.PHONY: $(BUILD) clean
$(BUILD):
@[ -d $@ ] || mkdir -p $@
@$(MAKE) --no-print-directory -C $(BUILD) -f $(ROOT)/Makefile
clean:
@echo "[RM] $(notdir $(OUTPUT))"
@rm -rf $(BUILD) $(OUTPUT).elf $(OUTPUT).rpx $(OUTPUT).a
else
DEPENDS := $(OFILES:.o=.d)
$(OUTPUT).rpx: $(OUTPUT).elf
$(OUTPUT).elf: $(OFILES)
-include $(DEPENDS)
endif

176
samples/pong/src/draw.c Executable file
View File

@ -0,0 +1,176 @@
#include "draw.h"
#include <coreinit/cache.h>
#include <coreinit/screen.h>
void *screenBuffer;
void flipBuffers()
{
//Grab the buffer size for each screen (TV and gamepad)
int buf0_size = OSScreenGetBufferSizeEx(0);
int buf1_size = OSScreenGetBufferSizeEx(1);
//Flush the cache
DCFlushRange((void *)screenBuffer + buf0_size, buf1_size);
DCFlushRange((void *)screenBuffer, buf0_size);
//Flip the buffer
OSScreenFlipBuffersEx(0);
OSScreenFlipBuffersEx(1);
}
void drawString(int x, int y, char * string)
{
OSScreenPutFontEx(0, x, y, string);
OSScreenPutFontEx(1, x, y, string);
}
void fillScreen(char r,char g,char b,char a)
{
uint32_t num = (r << 24) | (g << 16) | (b << 8) | a;
OSScreenClearBufferEx(0, num);
OSScreenClearBufferEx(1, num);
}
//Rendering in
void drawPixel(int x, int y, char r, char g, char b, char a)
{
uint32_t num = (r << 24) | (g << 16) | (b << 8) | a;
OSScreenPutPixelEx(0,x*2,y*2,num);
OSScreenPutPixelEx(1,x*2,y*2,num);
OSScreenPutPixelEx(0,x*2+1,y*2,num);
OSScreenPutPixelEx(1,x*2+1,y*2,num);
OSScreenPutPixelEx(0,x*2,y*2+1,num);
OSScreenPutPixelEx(1,x*2,y*2+1,num);
OSScreenPutPixelEx(0,x*2+1,y*2+1,num);
OSScreenPutPixelEx(1,x*2+1,y*2+1,num);
//Code to write to framebuffer directly. For some reason this is only writing to one of the framebuffers when calling flipBuffers. Should provide speedup but needs investigation.
/*
int buf0_size = OSScreenGetBufferSizeEx(0);
int height = 1024;
int width = 1280;
char *screen = (void *)screenBuffer;
uint32_t v=(x + y*width)*4;
screen[v]=r;
screen[v+1]=g;
screen[v+2]=b;
screen[v+3]=a;
height = 480;
width = 896;
char *screen2 = (void *)screenBuffer + buf0_size;
v=(x + y*width)*4;
screen2[v]=r;
screen2[v+1]=g;
screen2[v+2]=b;
screen2[v+3]=a;
*/
}
void drawLine(int x1, int y1, int x2, int y2, char r, char g, char b, char a)
{
int x, y;
if (x1 == x2){
if (y1 < y2) for (y = y1; y <= y2; y++) drawPixel(x1, y, r, g, b, a);
else for (y = y2; y <= y1; y++) drawPixel(x1, y, r, g, b, a);
}
else {
if (x1 < x2) for (x = x1; x <= x2; x++) drawPixel(x, y1, r, g, b, a);
else for (x = x2; x <= x1; x++) drawPixel(x, y1, r, g, b, a);
}
}
void drawRect(int x1, int y1, int x2, int y2, char r, char g, char b, char a)
{
drawLine(x1, y1, x2, y1, r, g, b, a);
drawLine(x2, y1, x2, y2, r, g, b, a);
drawLine(x1, y2, x2, y2, r, g, b, a);
drawLine(x1, y1, x1, y2, r, g, b, a);
}
void drawFillRect(int x1, int y1, int x2, int y2, char r, char g, char b, char a)
{
int X1, X2, Y1, Y2, i, j;
if (x1 < x2){
X1 = x1;
X2 = x2;
}
else {
X1 = x2;
X2 = x1;
}
if (y1 < y2){
Y1 = y1;
Y2 = y2;
}
else {
Y1 = y2;
Y2 = y1;
}
for (i = X1; i <= X2; i++){
for (j = Y1; j <= Y2; j++){
drawPixel(i, j, r, g, b, a);
}
}
}
void drawCircle(int xCen, int yCen, int radius, char r, char g, char b, char a)
{
int x = 0;
int y = radius;
int p = (5 - radius * 4) / 4;
drawCircleCircum(xCen, yCen, x, y, r, g, b, a);
while (x < y){
x++;
if (p < 0){
p += 2 * x + 1;
}
else{
y--;
p += 2 * (x - y) + 1;
}
drawCircleCircum(xCen, yCen, x, y, r, g, b, a);
}
}
void drawFillCircle(int xCen, int yCen, int radius, char r, char g, char b, char a)
{
drawCircle(xCen, yCen, radius, r, g, b, a);
int x, y;
for (y = -radius; y <= radius; y++){
for (x = -radius; x <= radius; x++)
if (x*x + y*y <= radius*radius + radius * .8f)
drawPixel(xCen + x, yCen + y, r, g, b, a);
}
}
void drawCircleCircum(int cx, int cy, int x, int y, char r, char g, char b, char a)
{
if (x == 0){
drawPixel(cx, cy + y, r, g, b, a);
drawPixel(cx, cy - y, r, g, b, a);
drawPixel(cx + y, cy, r, g, b, a);
drawPixel(cx - y, cy, r, g, b, a);
}
if (x == y){
drawPixel(cx + x, cy + y, r, g, b, a);
drawPixel(cx - x, cy + y, r, g, b, a);
drawPixel(cx + x, cy - y, r, g, b, a);
drawPixel(cx - x, cy - y, r, g, b, a);
}
if (x < y){
drawPixel(cx + x, cy + y, r, g, b, a);
drawPixel(cx - x, cy + y, r, g, b, a);
drawPixel(cx + x, cy - y, r, g, b, a);
drawPixel(cx - x, cy - y, r, g, b, a);
drawPixel(cx + y, cy + x, r, g, b, a);
drawPixel(cx - y, cy + x, r, g, b, a);
drawPixel(cx + y, cy - x, r, g, b, a);
drawPixel(cx - y, cy - x, r, g, b, a);
}
}

19
samples/pong/src/draw.h Executable file
View File

@ -0,0 +1,19 @@
#ifndef DRAW_H
#define DRAW_H
#include <coreinit/screen.h>
#include <wut_types.h>
void *screenBuffer;
//Function declarations for my graphics library
void flipBuffers();
void fillScreen(char r, char g, char b, char a);
void drawString(int x, int y, char * string);
void drawPixel(int x, int y, char r, char g, char b, char a);
void drawLine(int x1, int y1, int x2, int y2, char r, char g, char b, char a);
void drawRect(int x1, int y1, int x2, int y2, char r, char g, char b, char a);
void drawFillRect(int x1, int y1, int x2, int y2, char r, char g, char b, char a);
void drawCircle(int xCen, int yCen, int radius, char r, char g, char b, char a);
void drawFillCircle(int xCen, int yCen, int radius, char r, char g, char b, char a);
void drawCircleCircum(int cx, int cy, int x, int y, char r, char g, char b, char a);
#endif /* DRAW_H */

98
samples/pong/src/memory.c Normal file
View File

@ -0,0 +1,98 @@
/****************************************************************************
* Copyright (C) 2015 Dimok
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#include <malloc.h>
#include <string.h>
#include <coreinit/baseheap.h>
#include <coreinit/frameheap.h>
#include <coreinit/expandedheap.h>
#include "memory.h"
#define MEMORY_ARENA_1 0
#define MEMORY_ARENA_2 1
#define MEMORY_ARENA_3 2
#define MEMORY_ARENA_4 3
#define MEMORY_ARENA_5 4
#define MEMORY_ARENA_6 5
#define MEMORY_ARENA_7 6
#define MEMORY_ARENA_8 7
#define MEMORY_ARENA_FG_BUCKET 8
static void *mem1_heap;
static void *bucket_heap;
void memoryInitialize(void)
{
void *mem1_heap_handle = MEMGetBaseHeapHandle(MEMORY_ARENA_1);
unsigned int mem1_allocatable_size = MEMGetAllocatableSizeForFrmHeapEx(mem1_heap_handle, 4);
void *mem1_memory = MEMAllocFromFrmHeapEx(mem1_heap_handle, mem1_allocatable_size, 4);
if(mem1_memory)
mem1_heap = MEMCreateExpHeapEx(mem1_memory, mem1_allocatable_size, 0);
void *bucket_heap_handle = MEMGetBaseHeapHandle(MEMORY_ARENA_FG_BUCKET);
unsigned int bucket_allocatable_size = MEMGetAllocatableSizeForFrmHeapEx(bucket_heap_handle, 4);
void *bucket_memory = MEMAllocFromFrmHeapEx(bucket_heap_handle, bucket_allocatable_size, 4);
if(bucket_memory)
bucket_heap = MEMCreateExpHeapEx(bucket_memory, bucket_allocatable_size, 0);
}
void memoryRelease(void)
{
MEMDestroyExpHeap(mem1_heap);
MEMFreeToFrmHeap(MEMGetBaseHeapHandle(MEMORY_ARENA_1), 3);
mem1_heap = NULL;
MEMDestroyExpHeap(bucket_heap);
MEMFreeToFrmHeap(MEMGetBaseHeapHandle(MEMORY_ARENA_FG_BUCKET), 3);
bucket_heap = NULL;
}
//!-------------------------------------------------------------------------------------------
//! some wrappers
//!-------------------------------------------------------------------------------------------
void * MEM2_alloc(unsigned int size, unsigned int align)
{
return memalign(align, size);
}
void MEM2_free(void *ptr)
{
free(ptr);
}
void * MEM1_alloc(unsigned int size, unsigned int align)
{
if (align < 4)
align = 4;
return MEMAllocFromExpHeapEx(mem1_heap, size, align);
}
void MEM1_free(void *ptr)
{
MEMFreeToExpHeap(mem1_heap, ptr);
}
void * MEMBucket_alloc(unsigned int size, unsigned int align)
{
if (align < 4)
align = 4;
return MEMAllocFromExpHeapEx(bucket_heap, size, align);
}
void MEMBucket_free(void *ptr)
{
MEMFreeToExpHeap(bucket_heap, ptr);
}

42
samples/pong/src/memory.h Normal file
View File

@ -0,0 +1,42 @@
/****************************************************************************
* Copyright (C) 2015 Dimok
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#ifndef __MEMORY_H_
#define __MEMORY_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <malloc.h>
void memoryInitialize(void);
void memoryRelease(void);
void * MEM2_alloc(unsigned int size, unsigned int align);
void MEM2_free(void *ptr);
void * MEM1_alloc(unsigned int size, unsigned int align);
void MEM1_free(void *ptr);
void * MEMBucket_alloc(unsigned int size, unsigned int align);
void MEMBucket_free(void *ptr);
#ifdef __cplusplus
}
#endif
#endif // __MEMORY_H_

425
samples/pong/src/pong.c Executable file
View File

@ -0,0 +1,425 @@
#include "pong.h"
#include <stdlib.h>
#include <coreinit/internal.h>
//Sets a collsion box.
int collisionBox(int box1x, int box1y, int width1, int height1, int box2x, int box2y, int width2, int height2){
int corner1x = box1x + width1;
int corner1y = box1y - height1;
int corner2x = box2x + width2;
int corner2y = box2y - height2;
if (abs(box1x - corner2x)< 2 || abs(corner1x - box2x)< 2){
if ((box1y >= corner2y && box1y <= box2y) || (corner1y >= corner2y && corner1y <= box2y))return 1;
}
if (abs(box1y - corner2y) < 2 || abs(corner1y - box2y) < 2){
if ((box1x <= corner2x && box1x >= box2x) || (corner1x <= corner2x && corner1x >= box2x))return 2;
}
return 0;
}
//Updates player1 location
void p1Move(struct pongGlobals *myPongGlobals) {
if ((myPongGlobals->button & VPAD_BUTTON_LEFT) && myPongGlobals->p1X > myPongGlobals->xMinBoundry) {
//Trigger render flag
myPongGlobals->renderP1Flag = 1;
//Update player location
myPongGlobals->p1X--;
}
if ((myPongGlobals->button & VPAD_BUTTON_RIGHT) && myPongGlobals->p1X+myPongGlobals->p1X_size < myPongGlobals->xMaxBoundry/4) {
myPongGlobals->p1X++;
//Trigger render flag
myPongGlobals->renderP1Flag = 1;
}
if ((myPongGlobals->button & VPAD_BUTTON_UP) && myPongGlobals->p1Y-myPongGlobals->p1Y_size > myPongGlobals->yMinBoundry) {
//Trigger render flag
myPongGlobals->renderP1Flag = 1;
//Update player location
myPongGlobals->p1Y--;
}
if ((myPongGlobals->button & VPAD_BUTTON_DOWN) && myPongGlobals->p1Y < myPongGlobals->yMaxBoundry) {
myPongGlobals->p1Y++;
//Trigger render flag
myPongGlobals->renderP1Flag = 1;
}
};
//Updates player1 location
void p2Move(struct pongGlobals *myPongGlobals) {
if ((myPongGlobals->button & VPAD_BUTTON_Y) && myPongGlobals->p2X > myPongGlobals->xMaxBoundry-myPongGlobals->xMaxBoundry/4) {
//Trigger render flag
myPongGlobals->renderP2Flag = 1;
//Update player location
myPongGlobals->p2X--;
}
if ((myPongGlobals->button & VPAD_BUTTON_A) && myPongGlobals->p2X+myPongGlobals->p2X_size < myPongGlobals->xMaxBoundry) {
myPongGlobals->p2X++;
//Trigger render flag
myPongGlobals->renderP2Flag = 1;
}
if ((myPongGlobals->button & VPAD_BUTTON_X) && myPongGlobals->p2Y-myPongGlobals->p2Y_size > myPongGlobals->yMinBoundry) {
//Trigger render flag
myPongGlobals->renderP2Flag = 1;
//Update player location
myPongGlobals->p2Y--;
}
if ((myPongGlobals->button & VPAD_BUTTON_B) && myPongGlobals->p2Y < myPongGlobals->yMaxBoundry) {
myPongGlobals->p2Y++;
//Trigger render flag
myPongGlobals->renderP2Flag = 1;
}
};
//Physics for ball
void moveBall(struct pongGlobals *myPongGlobals) {
int jump = 1;
//Don't move at all
if (myPongGlobals->flag)jump = 4;
switch (myPongGlobals->direction) {
case 1:
myPongGlobals->ballX -= jump; //down left
myPongGlobals->ballY += jump;
break;
case 3:
myPongGlobals->ballX += jump; //down right
myPongGlobals->ballY += jump;
break;
case 2:
myPongGlobals->ballX += jump; //up right
myPongGlobals->ballY -= jump;
break;
case 0:
myPongGlobals->ballX -= jump; //up left
myPongGlobals->ballY -= jump;
break;
default:
break;
}
myPongGlobals->flag = 0;
};
//Checks for collsions
void checkCollision(struct pongGlobals *myPongGlobals) {
int old;
old = myPongGlobals->direction;
if (myPongGlobals->ballY-myPongGlobals->ballY_size < myPongGlobals->yMinBoundry) {
myPongGlobals->direction ^= 1;
}
/*
if (myPongGlobals->ballX < myPongGlobals->xMinBoundry) {
myPongGlobals->direction ^= 2;
}
if (myPongGlobals->ballX > myPongGlobals->xMaxBoundry) {
myPongGlobals->direction ^= 2;
}
*/
if (myPongGlobals->ballY > myPongGlobals->yMaxBoundry) {
myPongGlobals->direction ^= 1;
}
//if (myPongGlobals->ballX < myPongGlobals->p1X+myPongGlobals->p1X_size+2)
{
//Check p1 collision
if (collisionBox(myPongGlobals->ballX, myPongGlobals->ballY, myPongGlobals->ballX_size, myPongGlobals->ballY_size, myPongGlobals->p1X, myPongGlobals->p1Y_old, myPongGlobals->p1X_size, myPongGlobals->p1Y_size) == 1) {
myPongGlobals->direction ^= 2;
}
else if (collisionBox(myPongGlobals->ballX, myPongGlobals->ballY, myPongGlobals->ballX_size, myPongGlobals->ballY_size, myPongGlobals->p1X, myPongGlobals->p1Y, myPongGlobals->p1X_size, myPongGlobals->p1Y_size) == 2)
{
myPongGlobals->direction ^= 1;
}
}
//if (myPongGlobals->ballX+myPongGlobals->ballX_size > myPongGlobals->p2X-2)
{
//Check p2 collision
if (collisionBox(myPongGlobals->ballX, myPongGlobals->ballY, myPongGlobals->ballX_size, myPongGlobals->ballY_size, myPongGlobals->p2X, myPongGlobals->p2Y, myPongGlobals->p2X_size, myPongGlobals->p2Y_size) == 1) {
myPongGlobals->direction ^= 2;
}
else if (collisionBox(myPongGlobals->ballX, myPongGlobals->ballY, myPongGlobals->ballX_size, myPongGlobals->ballY_size, myPongGlobals->p2X, myPongGlobals->p2Y, myPongGlobals->p2X_size, myPongGlobals->p2Y_size) == 2)
{
myPongGlobals->direction ^= 1;
}
}
if ((myPongGlobals->direction ^ old) != 0)myPongGlobals->flag = 1;
if (myPongGlobals->ballX+myPongGlobals->ballX_size >= myPongGlobals->xMaxBoundry)
{
myPongGlobals->score1++;
checkWin(myPongGlobals);
}
if (myPongGlobals->ballX <= myPongGlobals->xMinBoundry)
{
myPongGlobals->score2++;
checkWin(myPongGlobals);
}
};
//Checks to see if we have meet the requirements for entering the win state
void checkWin(struct pongGlobals *myPongGlobals) {
if (myPongGlobals->score1 > myPongGlobals->scoreWin) {
myPongGlobals->score1 = 0;
myPongGlobals->renderWinFlag = 1;
myPongGlobals->winningPlayer = 1;
}
if (myPongGlobals->score2 > myPongGlobals->scoreWin) {
myPongGlobals->score2 = 0;
myPongGlobals->renderWinFlag = 1;
myPongGlobals->winningPlayer = 2;
}
reset(myPongGlobals);
};
//Render function for ball and updates player and balls new locations.
void renderBall(struct pongGlobals *myPongGlobals) {
drawFillRect(myPongGlobals->ballX_old, myPongGlobals->ballY_old - myPongGlobals->ballY_size, myPongGlobals->ballX_old + myPongGlobals->ballX_size, myPongGlobals->ballY_old, myPongGlobals->ballTrailColorR,myPongGlobals->ballTrailColorG,myPongGlobals->ballTrailColorB, 0);
drawFillRect(myPongGlobals->ballX, myPongGlobals->ballY - myPongGlobals->ballY_size, myPongGlobals->ballX + myPongGlobals->ballX_size, myPongGlobals->ballY, myPongGlobals->ballColorR, myPongGlobals->ballColorG, myPongGlobals->ballColorB, 0);
};
void render(struct pongGlobals *myPongGlobals)
{
for (int ii = 0; ii < 2; ii++)
{
if (myPongGlobals->renderResetFlag)
{
renderReset(myPongGlobals);
}
if (myPongGlobals->renderScoreFlag)
{
renderScore(myPongGlobals);
}
if (myPongGlobals->renderBallFlag)
{
renderBall(myPongGlobals);
}
if (myPongGlobals->renderWinFlag)
{
renderWin(myPongGlobals);
}
if (myPongGlobals->renderP1Flag)
{
renderP1(myPongGlobals);
}
if (myPongGlobals->renderP2Flag)
{
renderP2(myPongGlobals);
}
flipBuffers();
}
resetRenderFlags(myPongGlobals);
}
void resetRenderFlags(struct pongGlobals *myPongGlobals)
{
myPongGlobals->renderResetFlag = 0;
myPongGlobals->renderBallFlag = 0;
myPongGlobals->renderWinFlag = 0;
myPongGlobals->renderP1Flag = 0;
myPongGlobals->renderP2Flag = 0;
myPongGlobals->renderScoreFlag=0;
}
void updatePosition(struct pongGlobals *myPongGlobals)
{
myPongGlobals->p1X_old = myPongGlobals->p1X;
myPongGlobals->p1Y_old = myPongGlobals->p1Y;
myPongGlobals->p2X_old = myPongGlobals->p2X;
myPongGlobals->p2Y_old = myPongGlobals->p2Y;
myPongGlobals->ballX_old = myPongGlobals->ballX;
myPongGlobals->ballY_old = myPongGlobals->ballY;
}
//Reset the game
void reset(struct pongGlobals *myPongGlobals) {
//Set global variables to default state
myPongGlobals->ballX = myPongGlobals->ballX_default;
myPongGlobals->ballY = myPongGlobals->ballY_default;
myPongGlobals->p1X = myPongGlobals->p1X_default;
myPongGlobals->p1Y = myPongGlobals->p1Y_default;
myPongGlobals->p1X_old = myPongGlobals->p1X;
myPongGlobals->p1Y_old = myPongGlobals->p1Y;
myPongGlobals->p2X = myPongGlobals->p2X_default;
myPongGlobals->p2Y = myPongGlobals->p2Y_default;
myPongGlobals->p2X_old = myPongGlobals->p2X;
myPongGlobals->p2Y_old = myPongGlobals->p2Y;
myPongGlobals->ballX_old = myPongGlobals->ballX;
myPongGlobals->ballY_old = myPongGlobals->ballY;
myPongGlobals->direction = (myPongGlobals->count & 3);
myPongGlobals->button = 0;
//Set flag to render reset screen;
myPongGlobals->renderResetFlag = 1;
myPongGlobals->renderScoreFlag = 1;
};
void renderScore(struct pongGlobals *myPongGlobals)
{
char output1[255];
__os_snprintf(output1, 255, "%d", myPongGlobals->score1);
drawString(myPongGlobals->score1X, myPongGlobals->score1Y, output1);
char output2[255];
__os_snprintf(output2, 255, "%d", myPongGlobals->score2);
drawString(myPongGlobals->score2X, myPongGlobals->score2Y, output2);
}
void renderReset(struct pongGlobals *myPongGlobals)
{
fillScreen(myPongGlobals->backgroundColorR, myPongGlobals->backgroundColorG, myPongGlobals->backgroundColorB,0);
renderInitialPlayers(myPongGlobals);
}
//Sleeping function to kill time. Should probably update this to use tick.
void wait(int t) {
int i = 0;
int j = 0;
int z = 0;
for (i = 0; i < t; i++) {
for (j = 0; j < t; j++) {
z = i / 33;
}
}
};
//Draws the win screen.
void renderWin(struct pongGlobals *myPongGlobals) {
if (myPongGlobals->winningPlayer == 1) {
char p1win[255];
__os_snprintf(p1win, 255, "Player 1 Wins!");
drawString(myPongGlobals->winX, myPongGlobals->winY, p1win);
}
if (myPongGlobals->winningPlayer == 2) {
char p2win[255];
__os_snprintf(p2win, 255, "Player 2 Wins!");
drawString(myPongGlobals->winX, myPongGlobals->winY, p2win);
}
};
//Draws the inital player paddles and ball.
void renderInitialPlayers(struct pongGlobals *myPongGlobals) {
drawFillRect(myPongGlobals->p1X_old, myPongGlobals->p1Y_old - myPongGlobals->p1Y_size, myPongGlobals->p1X_old + myPongGlobals->p1X_size, myPongGlobals->p1Y_old, myPongGlobals->paddleColorR, myPongGlobals->paddleColorG, myPongGlobals->paddleColorB, 0);
drawFillRect(myPongGlobals->p2X_old, myPongGlobals->p2Y_old - myPongGlobals->p2Y_size, myPongGlobals->p2X_old + myPongGlobals->p2X_size, myPongGlobals->p2Y_old, myPongGlobals->paddleColorR, myPongGlobals->paddleColorG, myPongGlobals->paddleColorB, 0);
drawFillRect(myPongGlobals->ballX_old, myPongGlobals->ballY_old - myPongGlobals->ballY_size, myPongGlobals->ballX_old + myPongGlobals->ballX_size, myPongGlobals->ballY_old, myPongGlobals->ballColorR, myPongGlobals->ballColorG, myPongGlobals->ballColorB, 0);
char credits[255];
__os_snprintf(credits, 255, "Pong by Relys!");
drawString(myPongGlobals->winX, myPongGlobals->winY+1, credits);
};
//Draws player1's paddle
void renderP1(struct pongGlobals *myPongGlobals) {
//move up
if (myPongGlobals->p1Y_old>myPongGlobals->p1Y)
{
drawLine(myPongGlobals->p1X_old, myPongGlobals->p1Y_old, myPongGlobals->p1X_old + myPongGlobals->p1X_size, myPongGlobals->p1Y_old, myPongGlobals->backgroundColorR, myPongGlobals->backgroundColorG, myPongGlobals->backgroundColorB, 0);
drawLine(myPongGlobals->p1X, myPongGlobals->p1Y - myPongGlobals->p1Y_size, myPongGlobals->p1X + myPongGlobals->p1X_size, myPongGlobals->p1Y - myPongGlobals->p1Y_size, myPongGlobals->paddleColorR,myPongGlobals->paddleColorG, myPongGlobals->paddleColorB, 0);
}
//Move down
if(myPongGlobals->p1Y_old<myPongGlobals->p1Y)
{
drawLine(myPongGlobals->p1X, myPongGlobals->p1Y, myPongGlobals->p1X + myPongGlobals->p1X_size, myPongGlobals->p1Y, myPongGlobals->paddleColorR, myPongGlobals->paddleColorG, myPongGlobals->paddleColorB, 0);
drawLine(myPongGlobals->p1X_old, myPongGlobals->p1Y_old - myPongGlobals->p1Y_size, myPongGlobals->p1X_old + myPongGlobals->p1X_size, myPongGlobals->p1Y_old - myPongGlobals->p1Y_size, myPongGlobals->backgroundColorR, myPongGlobals->backgroundColorG, myPongGlobals->backgroundColorB, 0);
}
//Move right
if(myPongGlobals->p1X_old<myPongGlobals->p1X)
{
drawLine(myPongGlobals->p1X_old, myPongGlobals->p1Y_old-myPongGlobals->p1Y_size, myPongGlobals->p1X_old , myPongGlobals->p1Y_old, myPongGlobals->backgroundColorR, myPongGlobals->backgroundColorG, myPongGlobals->backgroundColorB, 0);
drawLine(myPongGlobals->p1X+myPongGlobals->p1X_size, myPongGlobals->p1Y-myPongGlobals->p1Y_size, myPongGlobals->p1X+myPongGlobals->p1X_size, myPongGlobals->p1Y, myPongGlobals->paddleColorR, myPongGlobals->paddleColorG, myPongGlobals->paddleColorB, 0);
}
//Move left
if(myPongGlobals->p1X_old>myPongGlobals->p1X)
{
drawLine(myPongGlobals->p1X, myPongGlobals->p1Y-myPongGlobals->p1Y_size, myPongGlobals->p1X , myPongGlobals->p1Y, myPongGlobals->paddleColorR, myPongGlobals->paddleColorG, myPongGlobals->paddleColorB, 0);
drawLine(myPongGlobals->p1X_old+myPongGlobals->p1X_size, myPongGlobals->p1Y_old-myPongGlobals->p1Y_size, myPongGlobals->p1X_old+myPongGlobals->p1X_size, myPongGlobals->p1Y_old, myPongGlobals->backgroundColorR, myPongGlobals->backgroundColorG, myPongGlobals->backgroundColorB, 0);
}
}
//Draws player2's paddle
void renderP2(struct pongGlobals *myPongGlobals) {
//move up
if (myPongGlobals->p2Y_old>myPongGlobals->p2Y)
{
drawLine(myPongGlobals->p2X_old, myPongGlobals->p2Y_old, myPongGlobals->p2X_old + myPongGlobals->p2X_size, myPongGlobals->p2Y_old, myPongGlobals->backgroundColorR, myPongGlobals->backgroundColorG, myPongGlobals->backgroundColorB, 0);
drawLine(myPongGlobals->p2X, myPongGlobals->p2Y - myPongGlobals->p2Y_size, myPongGlobals->p2X + myPongGlobals->p2X_size, myPongGlobals->p2Y - myPongGlobals->p2Y_size, myPongGlobals->paddleColorR,myPongGlobals->paddleColorG, myPongGlobals->paddleColorB, 0);
}
//Move down
if(myPongGlobals->p2Y_old<myPongGlobals->p2Y)
{
drawLine(myPongGlobals->p2X, myPongGlobals->p2Y, myPongGlobals->p2X + myPongGlobals->p2X_size, myPongGlobals->p2Y, myPongGlobals->paddleColorR, myPongGlobals->paddleColorG, myPongGlobals->paddleColorB, 0);
drawLine(myPongGlobals->p2X_old, myPongGlobals->p2Y_old - myPongGlobals->p2Y_size, myPongGlobals->p2X_old + myPongGlobals->p2X_size, myPongGlobals->p2Y_old - myPongGlobals->p2Y_size, myPongGlobals->backgroundColorR, myPongGlobals->backgroundColorG, myPongGlobals->backgroundColorB, 0);
}
//Move right
if(myPongGlobals->p2X_old<myPongGlobals->p2X)
{
drawLine(myPongGlobals->p2X_old, myPongGlobals->p2Y_old-myPongGlobals->p2Y_size, myPongGlobals->p2X_old , myPongGlobals->p2Y_old, myPongGlobals->backgroundColorR, myPongGlobals->backgroundColorG, myPongGlobals->backgroundColorB, 0);
drawLine(myPongGlobals->p2X+myPongGlobals->p2X_size, myPongGlobals->p2Y-myPongGlobals->p2Y_size, myPongGlobals->p2X+myPongGlobals->p2X_size, myPongGlobals->p2Y, myPongGlobals->paddleColorR, myPongGlobals->paddleColorG, myPongGlobals->paddleColorB, 0);
}
//Move left
if(myPongGlobals->p2X_old>myPongGlobals->p2X)
{
drawLine(myPongGlobals->p2X, myPongGlobals->p2Y-myPongGlobals->p2Y_size, myPongGlobals->p2X , myPongGlobals->p2Y, myPongGlobals->paddleColorR, myPongGlobals->paddleColorG, myPongGlobals->paddleColorB, 0);
drawLine(myPongGlobals->p2X_old+myPongGlobals->p2X_size, myPongGlobals->p2Y_old-myPongGlobals->p2Y_size, myPongGlobals->p2X_old+myPongGlobals->p2X_size, myPongGlobals->p2Y_old, myPongGlobals->backgroundColorR, myPongGlobals->backgroundColorG, myPongGlobals->backgroundColorB, 0);
}
}

109
samples/pong/src/pong.h Executable file
View File

@ -0,0 +1,109 @@
#ifndef PONG_H
#define PONG_H
#include <wut_types.h>
#include <vpad/input.h>
//Using modified version of draw to render at twice the scale to improve framerate
#include "draw.h"
//Struct for global variables for pong
struct pongGlobals{
//Flag for restarting the entire game.
int restart;
//Gameplay boundry
int xMinBoundry;
int xMaxBoundry;
int yMinBoundry;
int yMaxBoundry;
int scale;
int score1X;
int score2X;
int score1Y;
int score2Y;
int winX;
int winY;
//Globals for ball location and movement dx/dy
int ballX;
int ballX_old;
int ballY;
int ballY_old;
int ballX_size;
int ballY_size;
//Globals for player1 location and movement dx/dy
int p1X;
int p1X_old;
int p1Y;
int p1Y_old;
int p1X_size;
int p1Y_size;
//Globals for player2 location and movement dx/dy
int p2X;
int p2X_old;
int p2Y;
int p2Y_old;
int p2X_size;
int p2Y_size;
int p1X_default;
int p2X_default;
int ballX_default;
int p1Y_default;
int p2Y_default;
int ballY_default;
//Game engine globals
int direction;
uint32_t button;
int paddleColorR;
int paddleColorG;
int paddleColorB;
int ballColorR;
int ballColorG;
int ballColorB;
int ballTrailColorR;
int ballTrailColorG;
int ballTrailColorB;
int backgroundColorR;
int backgroundColorG;
int backgroundColorB;
int count;
int score1;
int score2;
int scoreWin;
int flag;
int winningPlayer;
int renderP1Flag;
int renderP2Flag;
int renderResetFlag;
int renderBallFlag;
int renderWinFlag;
int renderScoreFlag;
};
//Function declarations for pong functions.
void renderP2(struct pongGlobals *myPongGlobals);
void renderP1(struct pongGlobals *myPongGlobals);
void renderInitialPlayers(struct pongGlobals *myPongGlobals);
void renderWin(struct pongGlobals *myPongGlobals);
void wait(int t);
void renderReset(struct pongGlobals *myPongGlobals);
void renderScore(struct pongGlobals *myPongGlobals);
void reset(struct pongGlobals *myPongGlobals);
void updatePosition(struct pongGlobals *myPongGlobals);
void resetRenderFlags(struct pongGlobals *myPongGlobals);
void render(struct pongGlobals *myPongGlobals);
void renderBall(struct pongGlobals *myPongGlobals);
void checkWin(struct pongGlobals *myPongGlobals);
void checkCollision(struct pongGlobals *myPongGlobals);
void moveBall(struct pongGlobals *myPongGlobals);
void p2Move(struct pongGlobals *myPongGlobals);
void p1Move(struct pongGlobals *myPongGlobals);
int collisionBox(int box1x, int box1y, int width1, int height1, int box2x, int box2y, int width2, int height2);
#endif /* PONG_H */

184
samples/pong/src/program.c Executable file
View File

@ -0,0 +1,184 @@
#include "program.h"
#include <coreinit/debug.h>
#include <coreinit/internal.h>
#include <coreinit/screen.h>
#include <coreinit/exit.h>
#include <vpad/input.h>
#include <sysapp/switch.h>
#include <sysapp/launch.h>
#include "memory.h"
char log_buf[0x400];
int main(int argc, char **argv)
{
memoryInitialize();
OSReport("Memory initialized\n");
/****************************> Globals <****************************/
struct pongGlobals myPongGlobals;
//Flag for restarting the entire game.
myPongGlobals.restart = 1;
//scale of game
myPongGlobals.scale=1;
//Default locations for paddles and ball location and movement dx/dy
myPongGlobals.p1X_default=40*myPongGlobals.scale;
myPongGlobals.p2X_default=340*myPongGlobals.scale;
myPongGlobals.ballX_default=200*myPongGlobals.scale;
myPongGlobals.p1Y_default=150*myPongGlobals.scale;
myPongGlobals.p2Y_default=150*myPongGlobals.scale;
myPongGlobals.ballY_default=120*myPongGlobals.scale;
//Sizes of objects
myPongGlobals.p1X_size=20*myPongGlobals.scale;
myPongGlobals.p1Y_size=60*myPongGlobals.scale;
myPongGlobals.ballX_size=8*myPongGlobals.scale;
myPongGlobals.ballY_size=8*myPongGlobals.scale;
myPongGlobals.p2X_size=20*myPongGlobals.scale;
myPongGlobals.p2Y_size=60*myPongGlobals.scale;
//Boundry of play area (screen)
myPongGlobals.xMinBoundry=0*myPongGlobals.scale;
myPongGlobals.xMaxBoundry=400*myPongGlobals.scale;
myPongGlobals.yMinBoundry=0*myPongGlobals.scale;
myPongGlobals.yMaxBoundry=240*myPongGlobals.scale;
myPongGlobals.winX=11*2*myPongGlobals.scale;
myPongGlobals.winY=5*2*myPongGlobals.scale;
myPongGlobals.score1X=13*2*myPongGlobals.scale;
myPongGlobals.score2X=15*2*myPongGlobals.scale;
myPongGlobals.score1Y=0*myPongGlobals.scale;
myPongGlobals.score2Y=0*myPongGlobals.scale;
//Game engine globals
myPongGlobals.direction = 1;
myPongGlobals.button = 0;
myPongGlobals.paddleColorR=0xFF;
myPongGlobals.paddleColorG=0x00;
myPongGlobals.paddleColorB=0x00;
myPongGlobals.ballColorR=0x00;
myPongGlobals.ballColorG=0xFF;
myPongGlobals.ballColorB=0x00;
myPongGlobals.ballTrailColorR=0x00;
myPongGlobals.ballTrailColorG=0x00;
myPongGlobals.ballTrailColorB=0xFF;
myPongGlobals.backgroundColorR=0x00;
myPongGlobals.backgroundColorG=0x00;
myPongGlobals.backgroundColorB=0x00;
myPongGlobals.count = 0;
//Keep track of score
myPongGlobals.score1 = 0;
myPongGlobals.score2 = 0;
myPongGlobals.scoreWin = 9;
//Game engine globals
myPongGlobals.direction = 1;
myPongGlobals.button = 0;
myPongGlobals.paddleColorR=0xFF;
myPongGlobals.paddleColorG=0x00;
myPongGlobals.paddleColorB=0x00;
myPongGlobals.ballColorR=0x00;
myPongGlobals.ballColorG=0xFF;
myPongGlobals.ballColorB=0x00;
myPongGlobals.ballTrailColorR=0x00;
myPongGlobals.ballTrailColorG=0x00;
myPongGlobals.ballTrailColorB=0xFF;
myPongGlobals.backgroundColorR=0x00;
myPongGlobals.backgroundColorG=0x00;
myPongGlobals.backgroundColorB=0x00;
myPongGlobals.count = 0;
//Keep track of score
myPongGlobals.score1 = 0;
myPongGlobals.scoreWin = 9;
//Used for collision
myPongGlobals.flag = 0;
//Flag to determine if p1 should be rendered along with p1's movement direction
myPongGlobals.renderP1Flag = 0;
//Flags for render states
myPongGlobals.renderResetFlag = 0;
myPongGlobals.renderBallFlag = 0;
myPongGlobals.renderWinFlag = 0;
myPongGlobals.renderScoreFlag = 0;
OSReport("Globals initialized\n");
//Call the Screen initilzation function.
OSScreenInit();
OSReport("Screen initted\n");
//Grab the buffer size for each screen (TV and gamepad)
int buf0_size = OSScreenGetBufferSizeEx(0);
int buf1_size = OSScreenGetBufferSizeEx(1);
__os_snprintf(log_buf, 0x400, "Screen sizes %x, %x\n", buf0_size, buf1_size);
OSReport(log_buf);
//Set the buffer area.
screenBuffer = MEM1_alloc(buf0_size + buf1_size, 0x40);
__os_snprintf(log_buf, 0x400, "Allocated screen buffers at %x\n", screenBuffer);
OSReport(log_buf);
OSScreenSetBufferEx(0, screenBuffer);
OSScreenSetBufferEx(1, (screenBuffer + buf0_size));
OSReport("Set screen buffers\n");
OSScreenEnableEx(0, 1);
OSScreenEnableEx(1, 1);
//Clear both framebuffers.
for (int ii = 0; ii < 2; ii++)
{
fillScreen(0,0,0,0);
flipBuffers();
}
OSReport("Screen initialized\n");
/****************************> VPAD Loop <****************************/
int error;
VPADStatus vpad_data;
while (1)
{
VPADRead(0, &vpad_data, 1, &error);
//Get the status of the gamepad
myPongGlobals.button = vpad_data.hold;
//If the game has been restarted, reset the game (we do this one time in the beginning to set everything up)
if (myPongGlobals.restart == 1)
{
OSReport("Game reset\n");
reset(&myPongGlobals);
myPongGlobals.restart = 0;
}
//Set old positions.
updatePosition(&myPongGlobals);
//Update location of player1 and 2 paddles
p1Move(&myPongGlobals);
p2Move(&myPongGlobals);
//Update location of the ball
moveBall(&myPongGlobals);
//Check if their are any collisions between the ball and the paddles.
checkCollision(&myPongGlobals);
//Render the scene
myPongGlobals.renderBallFlag = 1;
render(&myPongGlobals);
//Increment the counter (used for physicals calcuations)
myPongGlobals.count+=1;
//To exit the game
if (myPongGlobals.button & VPAD_BUTTON_HOME)
{
break;
}
}
//WARNING: DO NOT CHANGE THIS. YOU MUST CLEAR THE FRAMEBUFFERS AND IMMEDIATELY CALL EXIT FROM THIS FUNCTION. RETURNING TO LOADER CAUSES FREEZE.
for(int ii = 0; ii < 2; ii++)
{
fillScreen(0,0,0,0);
flipBuffers();
}
//TODO: This doesn't work?
OSReport("Exiting to menu\n");
memoryRelease();
SYSLaunchMenu();
exit(0);
return 0;
}

11
samples/pong/src/program.h Executable file
View File

@ -0,0 +1,11 @@
#ifndef PROGRAM_H
#define PROGRAM_H
//Using modified version of draw to render at twice the scale to improve framerate
#include "draw.h"
#include "pong.h"
void _entryPoint();
#endif /* PROGRAM_H */