mirror of
https://github.com/joel16/PSPickr.git
synced 2024-11-26 21:10:27 +00:00
Initial commit
This commit is contained in:
commit
b97b42e153
54
.gitignore
vendored
Normal file
54
.gitignore
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Object files
|
||||
*.o
|
||||
*.ko
|
||||
*.obj
|
||||
*.elf
|
||||
|
||||
# Linker output
|
||||
*.ilk
|
||||
*.map
|
||||
*.exp
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Libraries
|
||||
*.lib
|
||||
*.la
|
||||
*.lo
|
||||
|
||||
# Shared objects (inc. Windows DLLs)
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.i*86
|
||||
*.x86_64
|
||||
*.hex
|
||||
*.PBP
|
||||
*.prx
|
||||
*.SFO
|
||||
|
||||
# Debug files
|
||||
*.dSYM/
|
||||
*.su
|
||||
*.idb
|
||||
*.pdb
|
||||
|
||||
# Kernel Module Compile Results
|
||||
*.mod*
|
||||
*.cmd
|
||||
.tmp_versions/
|
||||
modules.order
|
||||
Module.symvers
|
||||
Mkfile.old
|
||||
dkms.conf
|
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Joel
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
39
Makefile
Normal file
39
Makefile
Normal file
@ -0,0 +1,39 @@
|
||||
TARGET = PSPickr
|
||||
|
||||
SOURCES := data source
|
||||
CFILES := $(foreach dir, $(SOURCES), $(wildcard $(dir)/*.c))
|
||||
CPPFILES := $(foreach dir, $(SOURCES), $(wildcard $(dir)/*.cpp))
|
||||
GFXFILES := $(foreach dir, $(SOURCES), $(wildcard $(dir)/*.png))
|
||||
WAVFILES := $(foreach dir, $(SOURCES), $(wildcard $(dir)/*.wav))
|
||||
|
||||
OBJS := $(addsuffix .o,$(BINFILES)) $(CFILES:.c=.o) $(CPPFILES:.cpp=.o) $(GFXFILES:.png=.o) $(WAVFILES:.wav=.o)
|
||||
|
||||
VERSION_MAJOR := 1
|
||||
VERSION_MINOR := 0
|
||||
VERSION_MICRO := 0
|
||||
|
||||
INCDIR = libs/ libs/include include
|
||||
CFLAGS = -Os -Wall -ffast-math -Wno-narrowing -Wno-unused-variable \
|
||||
-DVERSION_MAJOR=$(VERSION_MAJOR) -DVERSION_MINOR=$(VERSION_MINOR) -DVERSION_MICRO=$(VERSION_MICRO)
|
||||
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti -std=gnu++17
|
||||
ASFLAGS := $(CFLAGS)
|
||||
|
||||
BUILD_PRX = 1
|
||||
PSP_LARGE_MEMORY = 1
|
||||
|
||||
LIBDIR = libs/lib
|
||||
LDFLAGS =
|
||||
LIBS = -lintrafont -lglib2d -ljpeg -lpng16 -lstdc++ -lz -lpspgu -lpspvram -lpspaudiolib -lpspaudio -lpspreg
|
||||
|
||||
EXTRA_TARGETS = EBOOT.PBP
|
||||
PSP_EBOOT_TITLE = PSPickr v$(VERSION_MAJOR).$(VERSION_MINOR)$(VERSION_MICRO)
|
||||
# PSP_EBOOT_ICON = ICON0.PNG
|
||||
|
||||
PSPSDK=$(shell psp-config --pspsdk-path)
|
||||
include $(PSPSDK)/lib/build.mak
|
||||
|
||||
%.o: %.png
|
||||
bin2o -i $< $@ $(addsuffix _png, $(basename $(notdir $<) ))
|
||||
|
||||
%.o: %.wav
|
||||
bin2o -i $< $@ $(addsuffix _wav, $(basename $(notdir $<) ))
|
BIN
data/game_over.wav
Normal file
BIN
data/game_over.wav
Normal file
Binary file not shown.
BIN
data/lives.png
Normal file
BIN
data/lives.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 606 B |
BIN
data/nope.wav
Normal file
BIN
data/nope.wav
Normal file
Binary file not shown.
12
include/audio.hpp
Normal file
12
include/audio.hpp
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace Audio {
|
||||
void Init(void);
|
||||
void Exit(void);
|
||||
int InitGameOverWav(void);
|
||||
int InitNopeWav(void);
|
||||
void PlayGameOverWav(void);
|
||||
void PlayNopeWav(void);
|
||||
}
|
8350
include/dr_wav.h
Normal file
8350
include/dr_wav.h
Normal file
File diff suppressed because it is too large
Load Diff
9
include/fs.hpp
Normal file
9
include/fs.hpp
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace FS {
|
||||
bool FileExists(const std::string &path);
|
||||
int ReadFile(const std::string &path, void *buf, int size);
|
||||
int WriteFile(const std::string &path, void *buf, int size);
|
||||
}
|
6
include/game.hpp
Normal file
6
include/game.hpp
Normal file
@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
namespace Game {
|
||||
void MainMenu(void);
|
||||
void Loop(void);
|
||||
}
|
18
include/gui.hpp
Normal file
18
include/gui.hpp
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <glib2d.h>
|
||||
#include <intraFont.h>
|
||||
#include <string>
|
||||
|
||||
extern intraFont *g_font;
|
||||
extern bool g_running;
|
||||
|
||||
namespace GUI {
|
||||
void DrawRect(float x, float y, float width, float height, g2dColor colour);
|
||||
void DrawImage(g2dTexture *tex, float x, float y, float w, float h);
|
||||
void DrawImageTint(g2dTexture *tex, float x, float y, float w, float h, g2dColor colour);
|
||||
void FontSetStyle(float size, unsigned int colour, unsigned int options);
|
||||
float GetTextHeight(void);
|
||||
float GetTextWidth(const std::string &text);
|
||||
float DrawText(float x, float y, const std::string &text);
|
||||
}
|
9
include/textures.hpp
Normal file
9
include/textures.hpp
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <glib2d.h>
|
||||
|
||||
namespace Textures {
|
||||
void Init(void);
|
||||
void Exit(void);
|
||||
g2dTexture *GetLives(void);
|
||||
}
|
22
include/utils.hpp
Normal file
22
include/utils.hpp
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <pspctrl.h>
|
||||
#include <psptypes.h>
|
||||
|
||||
/// Checks whether a result code indicates success.
|
||||
#define R_SUCCEEDED(res) ((res) >= 0)
|
||||
/// Checks whether a result code indicates failure.
|
||||
#define R_FAILED(res) ((res) < 0)
|
||||
|
||||
extern enum PspCtrlButtons PSP_CTRL_ENTER, PSP_CTRL_CANCEL;
|
||||
|
||||
namespace Utils {
|
||||
void SetBounds(int &set, int min, int max);
|
||||
int ReadControls(void);
|
||||
int IsButtonPressed(enum PspCtrlButtons buttons);
|
||||
int IsButtonHeld(enum PspCtrlButtons buttons);
|
||||
enum PspCtrlButtons GetEnterButton(void);
|
||||
enum PspCtrlButtons GetCancelButton(void);
|
||||
float GetAnalogX(void);
|
||||
float GetAnalogY(void);
|
||||
}
|
778
libs/include/glib2d.h
Normal file
778
libs/include/glib2d.h
Normal file
@ -0,0 +1,778 @@
|
||||
/** \mainpage gLib2D Documentation
|
||||
*
|
||||
* \section intro Introduction
|
||||
*
|
||||
* gLib2D by Geecko - A simple, fast, light-weight 2D graphics library. \n\n
|
||||
* This library has been designed to replace the old graphics.c library
|
||||
* and to simplify the use of pspgu.\n
|
||||
* The goals : keep it simple, keep it small, keep it fast.
|
||||
*
|
||||
* \section limits Known limitations
|
||||
*
|
||||
* - Draw & display buffers can't actually be used as real textures. Just a way
|
||||
* to get the vram pointer.
|
||||
* - No support for multiples contexts (e.g. sharing coordinates beetween
|
||||
* textures using some gBegin calls at a time).
|
||||
* - Manipulating textures (clear, get pixel info...) is not possible.
|
||||
* - When some 512*512 rotated, colorized and scaled textures are rendered
|
||||
* at a time, the framerate *could* go under 60 fps.
|
||||
*
|
||||
* \section install Installation
|
||||
*
|
||||
* - Simply put glib2d.c and glib2d.h in your source directory. \n
|
||||
* - Then add glib2d.o and link "-lpng -ljpeg -lz -lpspgu -lm -lpspvram"
|
||||
* in your Makefile.
|
||||
* - You're done !
|
||||
*
|
||||
* \section copyright License
|
||||
*
|
||||
* This work is licensed under the LGPLv3 License. \n
|
||||
* See the LICENSE file for more details. \n
|
||||
* You can support the library by marking your homebrew with
|
||||
* "Using gLib2D by Geecko".
|
||||
*
|
||||
* \section contact Contact
|
||||
*
|
||||
* Please report bugs or submit ideas at : \n geecko.dev@free.fr \n\n
|
||||
* Get the full documentation on : \n http://geecko.dev.free.fr \n\n
|
||||
* Also stay tuned on... \n
|
||||
* https://github.com/GeeckoDev (contributors would be a plus!) \n
|
||||
* http://twitter.com/GeeckoDev
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file glib2d.h
|
||||
* \brief gLib2D Header
|
||||
* \version Beta 5
|
||||
*/
|
||||
|
||||
#ifndef GLIB2D_H
|
||||
#define GLIB2D_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* \def G2D_SCR_W
|
||||
* \brief Screen width constant, in pixels.
|
||||
*/
|
||||
/**
|
||||
* \def G2D_SCR_H
|
||||
* \brief Screen height constant, in pixels.
|
||||
*/
|
||||
#define G2D_SCR_W (480)
|
||||
#define G2D_SCR_H (272)
|
||||
|
||||
/**
|
||||
* \def G2D_RGBA(r,g,b,a)
|
||||
* \brief Create a g2dColor.
|
||||
*
|
||||
* This macro creates a g2dColor from 4 values, red, green, blue and alpha.
|
||||
* Input range is from 0 to 255.
|
||||
*/
|
||||
#define G2D_RGBA(r, g, b, a) ((r)|((g)<<8)|((b)<<16)|((a)<<24))
|
||||
|
||||
/**
|
||||
* \def G2D_GET_R(color)
|
||||
* \brief Get red channel value from a g2dColor.
|
||||
*/
|
||||
/**
|
||||
* \def G2D_GET_G(color)
|
||||
* \brief Get green channel value from a g2dColor.
|
||||
*/
|
||||
/**
|
||||
* \def G2D_GET_B(color)
|
||||
* \brief Get blue channel value from a g2dColor.
|
||||
*/
|
||||
/**
|
||||
* \def G2D_GET_A(color)
|
||||
* \brief Get alpha channel value from a g2dColor.
|
||||
*/
|
||||
#define G2D_GET_R(color) (((color) ) & 0xFF)
|
||||
#define G2D_GET_G(color) (((color) >> 8) & 0xFF)
|
||||
#define G2D_GET_B(color) (((color) >> 16) & 0xFF)
|
||||
#define G2D_GET_A(color) (((color) >> 24) & 0xFF)
|
||||
|
||||
/**
|
||||
* \def G2D_MODULATE(color,luminance,alpha)
|
||||
* \brief g2dColor modulation.
|
||||
*
|
||||
* This macro modulates the luminance & alpha of a g2dColor.
|
||||
* Input range is from 0 to 255.
|
||||
*/
|
||||
#define G2D_MODULATE(color,luminance,alpha) \
|
||||
G2D_RGBA((int)(luminance) * G2D_GET_R(color) / 255, \
|
||||
(int)(luminance) * G2D_GET_G(color) / 255, \
|
||||
(int)(luminance) * G2D_GET_B(color) / 255, \
|
||||
(int)(alpha ) * G2D_GET_A(color) / 255)
|
||||
|
||||
/**
|
||||
* \enum g2dColors
|
||||
* \brief Colors enumeration.
|
||||
*
|
||||
* Primary, secondary, tertiary and grayscale colors are defined.
|
||||
*/
|
||||
enum g2dColors {
|
||||
// Primary colors
|
||||
RED = 0xFF0000FF,
|
||||
GREEN = 0xFF00FF00,
|
||||
BLUE = 0xFFFF0000,
|
||||
// Secondary colors
|
||||
CYAN = 0xFFFFFF00,
|
||||
MAGENTA = 0xFFFF00FF,
|
||||
YELLOW = 0xFF00FFFF,
|
||||
// Tertiary colors
|
||||
AZURE = 0xFFFF7F00,
|
||||
VIOLET = 0xFFFF007F,
|
||||
ROSE = 0xFF7F00FF,
|
||||
ORANGE = 0xFF007FFF,
|
||||
CHARTREUSE = 0xFF00FF7F,
|
||||
SPRING_GREEN = 0xFF7FFF00,
|
||||
// Grayscale
|
||||
WHITE = 0xFFFFFFFF,
|
||||
LITEGRAY = 0xFFBFBFBF,
|
||||
GRAY = 0xFF7F7F7F,
|
||||
DARKGRAY = 0xFF3F3F3F,
|
||||
BLACK = 0xFF000000
|
||||
};
|
||||
|
||||
/**
|
||||
* \enum g2dCoord_Mode
|
||||
* \brief Coordinates modes enumeration.
|
||||
*
|
||||
* Choose where the coordinates correspond in the object.
|
||||
* Can only be used with g2dSetCoordMode.
|
||||
*/
|
||||
/**
|
||||
* \enum g2dLine_Mode
|
||||
* \brief Line modes enumeration.
|
||||
*
|
||||
* Change line draw properties.
|
||||
* Can only be used with g2dBeginLines.
|
||||
*/
|
||||
/**
|
||||
* \enum g2dFlip_Mode
|
||||
* \brief Flip modes enumeration.
|
||||
*
|
||||
* Change flip properties.
|
||||
* Can only be used with g2dFlip.
|
||||
*/
|
||||
/**
|
||||
* \enum g2dTex_Mode
|
||||
* \brief Texture modes enumeration.
|
||||
*
|
||||
* Change texture properties.
|
||||
* Can only be used with g2dTexLoad.
|
||||
*/
|
||||
typedef enum {
|
||||
G2D_UP_LEFT,
|
||||
G2D_UP_RIGHT,
|
||||
G2D_DOWN_RIGHT,
|
||||
G2D_DOWN_LEFT,
|
||||
G2D_CENTER
|
||||
} g2dCoord_Mode;
|
||||
typedef enum {
|
||||
G2D_STRIP = 1 /**< Make a line strip. */
|
||||
} g2dLine_Mode;
|
||||
typedef enum {
|
||||
G2D_VSYNC = 1 /**< Limit the FPS to 60 (synchronized with the screen).
|
||||
Better quality and less power consumption. */
|
||||
} g2dFlip_Mode;
|
||||
typedef enum {
|
||||
G2D_SWIZZLE = 1 /**< Recommended. Use it to speedup rendering. */
|
||||
} g2dTex_Mode;
|
||||
|
||||
/**
|
||||
* \var g2dAlpha
|
||||
* \brief Alpha type.
|
||||
*/
|
||||
/**
|
||||
* \var g2dColor
|
||||
* \brief Color type.
|
||||
*/
|
||||
typedef int g2dAlpha;
|
||||
typedef unsigned int g2dColor;
|
||||
|
||||
/**
|
||||
* \struct g2dTexture
|
||||
* \brief Texture structure.
|
||||
*/
|
||||
typedef struct {
|
||||
int tw; /**< Real texture width. A power of two. */
|
||||
int th; /**< Real texture height. A power of two. */
|
||||
int w; /**< Texture width, as seen when drawing. */
|
||||
int h; /**< Texture height, as seen when drawing. */
|
||||
float ratio; /**< Width/height ratio. */
|
||||
bool swizzled; /**< Is the texture swizzled ? */
|
||||
g2dColor *data; /**< Pointer to raw data. */
|
||||
} g2dTexture;
|
||||
|
||||
/**
|
||||
* \var g2d_draw_buffer
|
||||
* \brief The current draw buffer as a texture.
|
||||
*/
|
||||
/**
|
||||
* \var g2d_disp_buffer
|
||||
* \brief The current display buffer as a texture.
|
||||
*/
|
||||
extern g2dTexture g2d_draw_buffer;
|
||||
extern g2dTexture g2d_disp_buffer;
|
||||
|
||||
/**
|
||||
* \brief Initializes the library.
|
||||
*
|
||||
* This function will create a GU context and setup the display buffers.
|
||||
* Automatically called by the other functions.
|
||||
*/
|
||||
void g2dInit(void);
|
||||
|
||||
/**
|
||||
* \brief Shutdowns the library.
|
||||
*
|
||||
* This function will destroy the GU context.
|
||||
*/
|
||||
void g2dTerm(void);
|
||||
|
||||
/**
|
||||
* \brief Clears screen & depth buffer.
|
||||
* @param color Screen clear color
|
||||
*
|
||||
* This function clears the screen, and clears the zbuffer if depth coordinate
|
||||
* is used in the loop. Will automatically init the GU if needed.
|
||||
*/
|
||||
void g2dClear(g2dColor color);
|
||||
|
||||
/**
|
||||
* \brief Clears depth buffer.
|
||||
*
|
||||
* This function clears the zbuffer to zero (z range 0-65535).
|
||||
* Will automatically init the GU if needed.
|
||||
*/
|
||||
void g2dClearZ(void);
|
||||
|
||||
/**
|
||||
* \brief Begins rectangles rendering.
|
||||
* @param tex Pointer to a texture, pass NULL to get a colored rectangle.
|
||||
*
|
||||
* This function begins object rendering. Resets all properties.
|
||||
* One g2dAdd() call per object.
|
||||
* Only one texture can be used, but multiple objects can be rendered at a time.
|
||||
* g2dBegin*() / g2dEnd() couple can be called multiple times in the loop,
|
||||
* to render multiple textures.
|
||||
*/
|
||||
void g2dBeginRects(g2dTexture *tex);
|
||||
|
||||
/**
|
||||
* \brief Begins lines rendering.
|
||||
* @param line_mode A g2dLine_Mode constant.
|
||||
*
|
||||
* This function begins object rendering. Calls g2dReset().
|
||||
* Two g2dAdd() calls per object.
|
||||
* Pass G2D_LINE_STRIP to make a line strip (two calls, then one per object).
|
||||
*/
|
||||
void g2dBeginLines(g2dLine_Mode mode);
|
||||
|
||||
/**
|
||||
* \brief Begins quads rendering.
|
||||
* @param tex Pointer to a texture, pass NULL to get a colored quad.
|
||||
*
|
||||
* This function begins object rendering. Resets all properties.
|
||||
* Four g2dAdd() calls per object, first for the up left corner, then clockwise.
|
||||
* Only one texture can be used, but multiple objects can be rendered at a time.
|
||||
* g2dBegin*() / g2dEnd() couple can be called multiple times in the loop,
|
||||
* to render multiple textures.
|
||||
*/
|
||||
void g2dBeginQuads(g2dTexture *tex);
|
||||
|
||||
/**
|
||||
* \brief Begins points rendering.
|
||||
*
|
||||
* This function begins object rendering. Resets all properties.
|
||||
* One g2dAdd() call per object.
|
||||
*/
|
||||
void g2dBeginPoints(void);
|
||||
|
||||
/**
|
||||
* \brief Ends object rendering.
|
||||
*
|
||||
* This function ends object rendering. Must be called after g2dBegin*() to add
|
||||
* objects to the display list. Automatically adapts pspgu functionnalities
|
||||
* to get the best performance possible.
|
||||
*/
|
||||
void g2dEnd(void);
|
||||
|
||||
/**
|
||||
* \brief Resets current transformation and attribution.
|
||||
*
|
||||
* This function must be called during object rendering.
|
||||
* Calls g2dResetCoord(), g2dResetRotation(), g2dResetScale(),
|
||||
* g2dResetColor(), g2dResetAlpha(), g2dResetCrop() and g2dResetTex().
|
||||
*/
|
||||
void g2dReset(void);
|
||||
|
||||
/**
|
||||
* \brief Flips the screen.
|
||||
* @param flip_mode A g2dFlip_Mode constant.
|
||||
*
|
||||
* This function must be called at the end of the loop.
|
||||
* Renders the whole display list to the draw buffer.
|
||||
* Inverts framebuffers to display the whole thing.
|
||||
*/
|
||||
void g2dFlip(g2dFlip_Mode mode);
|
||||
|
||||
/**
|
||||
* \brief Pushes the current transformation & attribution to a new object.
|
||||
*
|
||||
* This function must be called during object rendering.
|
||||
*/
|
||||
void g2dAdd(void);
|
||||
|
||||
/**
|
||||
* \brief Saves the current transformation to stack.
|
||||
*
|
||||
* This function must be called during object rendering.
|
||||
* The stack is 64 saves high.
|
||||
* Use it like the OpenGL one.
|
||||
*/
|
||||
void g2dPush(void);
|
||||
|
||||
/**
|
||||
* \brief Restore the current transformation from stack.
|
||||
*
|
||||
* This function must be called during object rendering.
|
||||
* The stack is 64 saves high.
|
||||
* Use it like the OpenGL one.
|
||||
*/
|
||||
void g2dPop(void);
|
||||
|
||||
/**
|
||||
* \brief Creates a new blank texture.
|
||||
* @param w Width of the texture.
|
||||
* @param h Height of the texture.
|
||||
*
|
||||
* This function returns NULL on allocation fail.
|
||||
*/
|
||||
g2dTexture* g2dTexCreate(int w, int h);
|
||||
|
||||
/**
|
||||
* \brief Frees a texture & set its pointer to NULL.
|
||||
* @param tex Pointer to the variable which contains the texture pointer.
|
||||
*
|
||||
* This function is used to gain memory when a texture is useless.
|
||||
* Must pass the pointer to the variable which contains the pointer,
|
||||
* to set it to NULL (passing NULL to a g2dBegin* function is safe).
|
||||
*/
|
||||
void g2dTexFree(g2dTexture **tex);
|
||||
|
||||
/**
|
||||
* \brief Loads an image.
|
||||
* @param data RGBA texture buffer.
|
||||
* @param width Texture width.
|
||||
* @param height Texture height.
|
||||
* @param tex_mode A g2dTex_Mode constant.
|
||||
* @returns Pointer to the generated texture.
|
||||
*
|
||||
* Swizzling is enabled only for 16*16+ textures (useless on small textures), pass G2D_SWIZZLE to enable it.
|
||||
* Texture supported up to 512*512 in size only (hardware limitation).
|
||||
*/
|
||||
g2dTexture *g2dTexLoad(void *data, int width, int height, g2dTex_Mode mode);
|
||||
|
||||
/**
|
||||
* \brief Resets the current coordinates.
|
||||
*
|
||||
* This function must be called during object rendering.
|
||||
* Sets g2dSetCoordMode() to G2D_UP_LEFT and g2dSetCoordXYZ() to (0,0,0).
|
||||
*/
|
||||
void g2dResetCoord(void);
|
||||
|
||||
/**
|
||||
* \brief Set coordinate mode.
|
||||
* @param coord_mode A gCoord_Mode.
|
||||
*
|
||||
* This function must be called during object rendering.
|
||||
* Defines where the coordinates correspond in the object.
|
||||
*/
|
||||
void g2dSetCoordMode(g2dCoord_Mode mode);
|
||||
|
||||
/**
|
||||
* \brief Gets the current position.
|
||||
* @param x Pointer to save the current x (in pixels).
|
||||
* @param y Pointer to save the current y (in pixels).
|
||||
* @param z Pointer to save the current z (in pixels).
|
||||
*
|
||||
* This function must be called during object rendering.
|
||||
* Parameters are pointers to float, not int !
|
||||
* Pass NULL if not needed.
|
||||
*/
|
||||
void g2dGetCoordXYZ(float *x, float *y, float *z);
|
||||
|
||||
/**
|
||||
* \brief Sets the new position.
|
||||
* @param x New x, in pixels.
|
||||
* @param y New y, in pixels.
|
||||
*
|
||||
* This function must be called during object rendering.
|
||||
*/
|
||||
void g2dSetCoordXY(float x, float y);
|
||||
|
||||
/**
|
||||
* \brief Sets the new position, with depth support.
|
||||
* @param x New x, in pixels.
|
||||
* @param y New y, in pixels.
|
||||
* @param z New z, in pixels. (front 0-65535 back)
|
||||
*
|
||||
* This function must be called during object rendering.
|
||||
*/
|
||||
void g2dSetCoordXYZ(float x, float y, float z);
|
||||
|
||||
/**
|
||||
* \brief Sets the new position, relative to the current.
|
||||
* @param x New x increment, in pixels.
|
||||
* @param y New y increment, in pixels.
|
||||
*
|
||||
* This function must be called during object rendering.
|
||||
*/
|
||||
void g2dSetCoordXYRelative(float x, float y);
|
||||
|
||||
/**
|
||||
* \brief Sets the new position, with depth support, relative to the current.
|
||||
* @param x New x increment, in pixels.
|
||||
* @param y New y increment, in pixels.
|
||||
* @param z New z increment, in pixels.
|
||||
*
|
||||
* This function must be called during object rendering.
|
||||
*/
|
||||
void g2dSetCoordXYZRelative(float x, float y, float z);
|
||||
|
||||
/**
|
||||
* \brief Use integer coordinates.
|
||||
* @param use false to desactivate (better look, by default),
|
||||
true to activate (can be useful when you have glitches).
|
||||
*
|
||||
* This function must be called during object rendering.
|
||||
*/
|
||||
void g2dSetCoordInteger(bool use);
|
||||
|
||||
/**
|
||||
* \brief Resets the global scale.
|
||||
*
|
||||
* This function resets the global scale to 1.f.
|
||||
* Translations and scales are multiplied by this factor.
|
||||
*/
|
||||
void g2dResetGlobalScale(void);
|
||||
|
||||
/**
|
||||
* \brief Resets the current scale.
|
||||
*
|
||||
* This function must be called during object rendering.
|
||||
* Sets the scale to the current texture size or (10,10).
|
||||
*/
|
||||
void g2dResetScale(void);
|
||||
|
||||
/**
|
||||
* \brief Gets the global scale.
|
||||
* @param scale Pointer to save the global scale (factor).
|
||||
*
|
||||
* Pass NULL if not needed.
|
||||
*/
|
||||
void g2dGetGlobalScale(float *scale);
|
||||
|
||||
/**
|
||||
* \brief Gets the current scale.
|
||||
* @param w Pointer to save the current width (in pixels).
|
||||
* @param h Pointer to save the current height (in pixels).
|
||||
*
|
||||
* This function must be called during object rendering.
|
||||
* Parameters are pointers to float, not int !
|
||||
* Pass NULL if not needed.
|
||||
*/
|
||||
void g2dGetScaleWH(float *w, float *h);
|
||||
|
||||
/**
|
||||
* \brief Sets the global scale.
|
||||
*
|
||||
* Translations and scales are multiplied by this factor.
|
||||
*/
|
||||
void g2dSetGlobalScale(float scale);
|
||||
|
||||
/**
|
||||
* \brief Sets the new scale.
|
||||
* @param w Width scale factor.
|
||||
* @param h Height scale factor.
|
||||
*
|
||||
* This function must be called during object rendering.
|
||||
* g2dResetScale() is called, then width & height scale are
|
||||
* multiplied by these values.
|
||||
* Negative values can be passed to invert the texture.
|
||||
*/
|
||||
void g2dSetScale(float w, float h);
|
||||
|
||||
/**
|
||||
* \brief Sets the new scale, in pixels.
|
||||
* @param w New width, in pixels.
|
||||
* @param h New height, in pixels.
|
||||
*
|
||||
* This function must be called during object rendering.
|
||||
* Negative values can be passed to invert the texture.
|
||||
*/
|
||||
void g2dSetScaleWH(float w, float h);
|
||||
|
||||
/**
|
||||
* \brief Sets the new scale, relative to the current.
|
||||
* @param w Width scale factor.
|
||||
* @param h Height scale factor.
|
||||
*
|
||||
* This function must be called during object rendering.
|
||||
* Current width & height scale are multiplied by these values.
|
||||
* Negative values can be passed to invert the texture.
|
||||
*/
|
||||
void g2dSetScaleRelative(float w, float h);
|
||||
|
||||
/**
|
||||
* \brief Sets the new scale, in pixels, relative to the current.
|
||||
* @param w New width to increment, in pixels.
|
||||
* @param h New height to increment, in pixels.
|
||||
*
|
||||
* This function must be called during object rendering.
|
||||
* Negative values can be passed to invert the texture.
|
||||
*/
|
||||
void g2dSetScaleWHRelative(float w, float h);
|
||||
|
||||
/**
|
||||
* \brief Resets the current color.
|
||||
*
|
||||
* This function must be called during object rendering.
|
||||
* Sets g2dSetColor() to WHITE.
|
||||
*/
|
||||
void g2dResetColor(void);
|
||||
|
||||
/**
|
||||
* \brief Resets the current alpha.
|
||||
*
|
||||
* This function must be called during object rendering.
|
||||
* Sets g2dSetAlpha() to 255.
|
||||
*/
|
||||
void g2dResetAlpha(void);
|
||||
|
||||
/**
|
||||
* \brief Gets the current alpha.
|
||||
* @param alpha Pointer to save the current alpha (0-255).
|
||||
*
|
||||
* This function must be called during object rendering.
|
||||
* Pass NULL if not needed.
|
||||
*/
|
||||
void g2dGetAlpha(g2dAlpha *alpha);
|
||||
|
||||
/**
|
||||
* \brief Sets the new color.
|
||||
* @param color The new color.
|
||||
*
|
||||
* This function must be called during object rendering.
|
||||
* Can be used to colorize any object.
|
||||
*/
|
||||
void g2dSetColor(g2dColor color);
|
||||
|
||||
/**
|
||||
* \brief Sets the new alpha.
|
||||
* @param alpha The new alpha (0-255).
|
||||
*
|
||||
* This function must be called during object rendering.
|
||||
* Can be used to make any object transparent.
|
||||
*/
|
||||
void g2dSetAlpha(g2dAlpha alpha);
|
||||
|
||||
/**
|
||||
* \brief Sets the new alpha, relative to the current alpha.
|
||||
* @param alpha The new alpha increment.
|
||||
*
|
||||
* This function must be called during object rendering.
|
||||
* Can be used to make any object transparent.
|
||||
*/
|
||||
void g2dSetAlphaRelative(int alpha);
|
||||
|
||||
/**
|
||||
* \brief Resets the current rotation.
|
||||
*
|
||||
* This function must be called during object rendering.
|
||||
* Sets g2dSetRotation() to 0°.
|
||||
*/
|
||||
void g2dResetRotation(void);
|
||||
|
||||
/**
|
||||
* \brief Gets the current rotation, in radians.
|
||||
* @param radians Pointer to save the current rotation.
|
||||
*
|
||||
* This function must be called during object rendering.
|
||||
* Pass NULL if not needed.
|
||||
*/
|
||||
void g2dGetRotationRad(float *radians);
|
||||
|
||||
/**
|
||||
* \brief Gets the current rotation, in degrees.
|
||||
* @param degrees Pointer to save the current rotation.
|
||||
*
|
||||
* This function must be called during object rendering.
|
||||
* Pass NULL if not needed.
|
||||
*/
|
||||
void g2dGetRotation(float *degrees);
|
||||
|
||||
/**
|
||||
* \brief Sets the new rotation, in radians.
|
||||
* @param radians The new angle.
|
||||
*
|
||||
* This function must be called during object rendering.
|
||||
* The rotation center is the actual coordinates.
|
||||
*/
|
||||
void g2dSetRotationRad(float radians);
|
||||
|
||||
/**
|
||||
* \brief Sets the new rotation, in degrees.
|
||||
* @param degrees The new angle.
|
||||
*
|
||||
* This function must be called during object rendering.
|
||||
* The rotation center is the actual coordinates.
|
||||
*/
|
||||
void g2dSetRotation(float degrees);
|
||||
|
||||
/**
|
||||
* \brief Sets the new rotation, relative to the current, in radians.
|
||||
* @param radians The new angle increment.
|
||||
*
|
||||
* This function must be called during object rendering.
|
||||
* The rotation center is the actual coordinates.
|
||||
*/
|
||||
void g2dSetRotationRadRelative(float radians);
|
||||
|
||||
/**
|
||||
* \brief Sets the new rotation, relative to the current, in degrees.
|
||||
* @param degrees The new angle increment.
|
||||
*
|
||||
* This function must be called during object rendering.
|
||||
* The rotation center is the actual coordinates.
|
||||
*/
|
||||
void g2dSetRotationRelative(float degrees);
|
||||
|
||||
/**
|
||||
* \brief Resets the current crop.
|
||||
*
|
||||
* This function must be called during object rendering.
|
||||
* Sets g2dSetCropXY() to (0;0) and g2dSetCropWH() to (tex->w,tex->h).
|
||||
*/
|
||||
void g2dResetCrop(void);
|
||||
|
||||
/**
|
||||
* \brief Gets the current crop position.
|
||||
* @param x Pointer to save the current crop x.
|
||||
* @param y Pointer to save the current crop y.
|
||||
*
|
||||
* This function must be called during object rendering.
|
||||
* Pass NULL if not needed.
|
||||
*/
|
||||
void g2dGetCropXY(int *x, int *y);
|
||||
|
||||
/**
|
||||
* \brief Gets the current crop scale.
|
||||
* @param w Pointer to save the current crop width.
|
||||
* @param h Pointer to save the current crop height.
|
||||
*
|
||||
* This function must be called during object rendering.
|
||||
* Pass NULL if not needed.
|
||||
*/
|
||||
void g2dGetCropWH(int *w, int *h);
|
||||
|
||||
/**
|
||||
* \brief Sets the new crop position.
|
||||
* @param x New x, in pixels.
|
||||
* @param y New y, in pixels.
|
||||
*
|
||||
* This function must be called during object rendering. Defines crop position.
|
||||
* If the rectangle is larger or next to the texture, it will be repeated
|
||||
* when g2dSetTexRepeat is enabled. Useful for a tileset.
|
||||
*/
|
||||
void g2dSetCropXY(int x, int y);
|
||||
|
||||
/**
|
||||
* \brief Sets the new crop size.
|
||||
* @param w New width, in pixels.
|
||||
* @param h New height, in pixels.
|
||||
*
|
||||
* This function must be called during object rendering. Defines crop size.
|
||||
* If the rectangle is larger or next to the texture, it will be repeated
|
||||
* when g2dSetTexRepeat is enabled. Useful for a tileset.
|
||||
*/
|
||||
void g2dSetCropWH(int w, int h);
|
||||
|
||||
/**
|
||||
* \brief Sets the new crop position, relative to the current.
|
||||
* @param x New x increment, in pixels.
|
||||
* @param y New y increment, in pixels.
|
||||
*
|
||||
* This function must be called during object rendering. Defines crop position.
|
||||
* If the rectangle is larger or next to the texture, texture will be repeated
|
||||
* when g2dSetTexRepeat is enabled. Useful for a tileset.
|
||||
*/
|
||||
void g2dSetCropXYRelative(int x, int y);
|
||||
|
||||
/**
|
||||
* \brief Sets the new crop size, relative to the current.
|
||||
* @param w New width increment, in pixels.
|
||||
* @param h New height increment, in pixels.
|
||||
*
|
||||
* This function must be called during object rendering. Defines crop size.
|
||||
* If the rectangle is larger or next to the texture, texture will be repeated
|
||||
* when g2dSetTexRepeat is enabled. Useful for a tileset.
|
||||
*/
|
||||
void g2dSetCropWHRelative(int w, int h);
|
||||
|
||||
/**
|
||||
* \brief Resets texture properties.
|
||||
*
|
||||
* This function must be called during object rendering.
|
||||
*/
|
||||
void g2dResetTex(void);
|
||||
|
||||
/**
|
||||
* \brief Set texture wrap.
|
||||
* @param use true to repeat, false to clamp (by default).
|
||||
*
|
||||
* This function must be called during object rendering.
|
||||
*/
|
||||
void g2dSetTexRepeat(bool use);
|
||||
|
||||
/**
|
||||
* \brief Use the bilinear filter with the texture.
|
||||
* @param use true to activate (better look, by default).
|
||||
false to desactivate (better performance).
|
||||
*
|
||||
* This function must be called during object rendering.
|
||||
* Only useful when scaling.
|
||||
*/
|
||||
void g2dSetTexLinear(bool use);
|
||||
|
||||
/**
|
||||
* \brief Resets the draw zone to the entire screen.
|
||||
*
|
||||
* This function can be called everywhere in the loop.
|
||||
*/
|
||||
void g2dResetScissor(void);
|
||||
|
||||
/**
|
||||
* \brief Sets the draw zone.
|
||||
* @param x New x position.
|
||||
* @param y New y position.
|
||||
* @param w New width.
|
||||
* @param h New height.
|
||||
*
|
||||
* This function can be called everywhere in the loop.
|
||||
* Pixel draw will be skipped outside this rectangle.
|
||||
*/
|
||||
void g2dSetScissor(int x, int y, int w, int h);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
BIN
libs/lib/libglib2d.a
Normal file
BIN
libs/lib/libglib2d.a
Normal file
Binary file not shown.
70
source/audio.cpp
Normal file
70
source/audio.cpp
Normal file
@ -0,0 +1,70 @@
|
||||
#include <pspaudio.h>
|
||||
#include <pspaudiolib.h>
|
||||
#include <pspthreadman.h>
|
||||
|
||||
#include "audio.hpp"
|
||||
#define DR_WAV_IMPLEMENTATION
|
||||
#include "dr_wav.h"
|
||||
|
||||
extern unsigned char game_over_wav_start[], nope_wav_start[];
|
||||
extern unsigned int game_over_wav_size, nope_wav_size;
|
||||
|
||||
namespace Audio {
|
||||
static drwav game_over_wav, nope_wav;
|
||||
static drwav_uint64 frames_read = 0;
|
||||
static bool playing = false;
|
||||
|
||||
static void Decode(void *buf, unsigned int length, void *userdata) {
|
||||
drwav *wav = static_cast<drwav *>(userdata);
|
||||
frames_read += drwav_read_pcm_frames_s16(wav, static_cast<drwav_uint64>(length), static_cast<drwav_int16 *>(buf));
|
||||
|
||||
if (frames_read >= wav->totalPCMFrameCount) {
|
||||
playing = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Init(void) {
|
||||
pspAudioInit();
|
||||
}
|
||||
|
||||
void Exit(void) {
|
||||
playing = false;
|
||||
frames_read = 0;
|
||||
pspAudioEndPre();
|
||||
pspAudioEnd();
|
||||
drwav_uninit(&game_over_wav);
|
||||
drwav_uninit(&nope_wav);
|
||||
}
|
||||
|
||||
int InitGameOverWav(void) {
|
||||
if (!drwav_init_memory(&game_over_wav, game_over_wav_start, game_over_wav_size, nullptr))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int InitNopeWav(void) {
|
||||
if (!drwav_init_memory(&nope_wav, nope_wav_start, nope_wav_size, nullptr))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void Clear(void) {
|
||||
playing = true;
|
||||
pspAudioSetChannelCallback(0, nullptr, nullptr); // Clear channel callback
|
||||
frames_read = 0;
|
||||
}
|
||||
|
||||
void PlayGameOverWav(void) {
|
||||
Audio::Clear();
|
||||
drwav_seek_to_pcm_frame(&game_over_wav, 0);
|
||||
pspAudioSetChannelCallback(0, Audio::Decode, &game_over_wav);
|
||||
}
|
||||
|
||||
void PlayNopeWav(void) {
|
||||
Audio::Clear();
|
||||
drwav_seek_to_pcm_frame(&nope_wav, 0);
|
||||
pspAudioSetChannelCallback(0, Audio::Decode, &nope_wav);
|
||||
}
|
||||
}
|
35
source/fs.cpp
Normal file
35
source/fs.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
#include <pspiofilemgr.h>
|
||||
|
||||
#include "fs.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
namespace FS {
|
||||
bool FileExists(const std::string &path) {
|
||||
SceIoStat stat = { 0 };
|
||||
return sceIoGetstat(path.c_str(), &stat) >= 0;
|
||||
}
|
||||
|
||||
int ReadFile(const std::string &path, void *buf, int size) {
|
||||
SceUID file = 0;
|
||||
|
||||
if (R_SUCCEEDED(file = sceIoOpen(path.c_str(), PSP_O_RDONLY, 0))) {
|
||||
int read = sceIoRead(file, buf, size);
|
||||
sceIoClose(file);
|
||||
return read;
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
int WriteFile(const std::string &path, void *buf, int size) {
|
||||
SceUID file = 0;
|
||||
|
||||
if (R_SUCCEEDED(file = sceIoOpen(path.c_str(), PSP_O_WRONLY | PSP_O_CREAT | PSP_O_TRUNC, 0777))) {
|
||||
int written = sceIoWrite(file, buf, size);
|
||||
sceIoClose(file);
|
||||
return written;
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
}
|
278
source/game.cpp
Normal file
278
source/game.cpp
Normal file
@ -0,0 +1,278 @@
|
||||
#include <time.h>
|
||||
|
||||
#include "audio.hpp"
|
||||
#include "fs.hpp"
|
||||
#include "gui.hpp"
|
||||
#include "textures.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
namespace Game {
|
||||
static const float tex_size = 12.f;
|
||||
static int time_left = 0, diff = 0, stages = 0, max_stages = 0, lives = 0, matches = 0, row = 0, selection = 0;
|
||||
static bool pattern[16];
|
||||
static unsigned int color[3];
|
||||
|
||||
void MainMenu(void) {
|
||||
const std::string subtitle_0 = "One of these colours is not like the other one!";
|
||||
const std::string subtitle_1 = "Which one?";
|
||||
const std::string instruc_0 = "Press X to start new game (with timer)";
|
||||
const std::string instruc_1 = "Press [ ] to start new game (without timer)";
|
||||
const std::string instruc_2 = "Press Start to exit";
|
||||
const std::string text = "Based on Sean M. Tracey's Pickr";
|
||||
|
||||
g2dClear(WHITE);
|
||||
GUI::FontSetStyle(1.2f, G2D_RGBA(0, 0, 0, 0), INTRAFONT_ALIGN_LEFT);
|
||||
GUI::DrawText((480 - GUI::GetTextWidth("PSPickr")) / 2, 80, "PSPickr");
|
||||
|
||||
GUI::FontSetStyle(1.0f, G2D_RGBA(0, 0, 0, 200), INTRAFONT_ALIGN_LEFT);
|
||||
GUI::DrawText((480 - GUI::GetTextWidth(subtitle_0)) / 2, 95, subtitle_0);
|
||||
GUI::DrawText((480 - GUI::GetTextWidth(subtitle_1)) / 2, 110, subtitle_1);
|
||||
|
||||
GUI::FontSetStyle(0.8f, G2D_RGBA(0, 0, 0, 200), INTRAFONT_ALIGN_LEFT);
|
||||
GUI::DrawText((480 - GUI::GetTextWidth(instruc_0)) / 2, 140, instruc_0);
|
||||
GUI::DrawText((480 - GUI::GetTextWidth(instruc_1)) / 2, 160, instruc_1);
|
||||
GUI::DrawText((480 - GUI::GetTextWidth(instruc_2)) / 2, 180, instruc_2);
|
||||
|
||||
GUI::FontSetStyle(0.8f, G2D_RGBA(0, 0, 0, 200), INTRAFONT_ALIGN_LEFT);
|
||||
intraFontPrintf(g_font, 10, 262, "Version %d.%d.%d", VERSION_MAJOR, VERSION_MINOR, VERSION_MICRO);
|
||||
GUI::DrawText((470 - GUI::GetTextWidth(text)), 262, text);
|
||||
g2dFlip(G2D_VSYNC);
|
||||
}
|
||||
|
||||
static void Init(void) {
|
||||
lives = 5;
|
||||
time_left = 480;
|
||||
diff = 10;
|
||||
stages = 0;
|
||||
row = 0;
|
||||
}
|
||||
|
||||
static void Fill(void) {
|
||||
for (unsigned int i = 0; i < 16; i++) {
|
||||
pattern[i] = false;
|
||||
}
|
||||
|
||||
pattern[rand() % 16] = true;
|
||||
color[0] = rand() % (255 - 2 * diff) + diff;
|
||||
color[1] = rand() % (255 - 2 * diff) + diff;
|
||||
color[2] = rand() % (255 - 2 * diff) + diff;
|
||||
}
|
||||
|
||||
static void Update(void) {
|
||||
diff = 10;
|
||||
}
|
||||
|
||||
static int GetHighscore(void) {
|
||||
char buf[10] = { 0 };
|
||||
int score = 0;
|
||||
|
||||
if (FS::FileExists("highscore.txt")) {
|
||||
FS::ReadFile("highscore.txt", buf, 10);
|
||||
std::sscanf(buf, "%d", &score);
|
||||
}
|
||||
|
||||
return score;
|
||||
}
|
||||
|
||||
static void SaveHighscore(void) {
|
||||
int score = Game::GetHighscore();
|
||||
|
||||
if (max_stages > score) {
|
||||
char buf[10] = { 0 };
|
||||
std::snprintf(buf, 10, "%d\n", max_stages);
|
||||
FS::WriteFile("highscore.txt", buf, 10);
|
||||
}
|
||||
}
|
||||
|
||||
static void Begin(bool timer) {
|
||||
int x, y;
|
||||
bool win = false, paused = false;
|
||||
|
||||
char stage_str[10], row_str[13];
|
||||
std::snprintf(stage_str, 10, "Score %d", stages);
|
||||
std::snprintf(row_str, 13, "%d in a row", row);
|
||||
|
||||
time_left = 480;
|
||||
Game::Fill();
|
||||
diff = (rand() % 2) ? diff : -diff;
|
||||
|
||||
while (true && time_left > 0 && lives > 0) {
|
||||
int ctrl = Utils::ReadControls();
|
||||
Utils::SetBounds(selection, 0, 15);
|
||||
|
||||
if (ctrl & PSP_CTRL_LEFT) {
|
||||
selection--;
|
||||
}
|
||||
else if (ctrl & PSP_CTRL_RIGHT) {
|
||||
selection++;
|
||||
}
|
||||
|
||||
if (ctrl & PSP_CTRL_UP) {
|
||||
selection -= 4;
|
||||
}
|
||||
else if (ctrl & PSP_CTRL_DOWN) {
|
||||
selection += 4;
|
||||
}
|
||||
|
||||
if (Utils::IsButtonPressed(PSP_CTRL_ENTER)) {
|
||||
if (!paused) {
|
||||
if (pattern[selection]) {
|
||||
win = true;
|
||||
}
|
||||
else {
|
||||
Audio::PlayNopeWav();
|
||||
lives--;
|
||||
row = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Utils::IsButtonPressed(PSP_CTRL_START)) {
|
||||
paused = !paused;
|
||||
}
|
||||
|
||||
y = 34;
|
||||
g2dClear(GRAY);
|
||||
|
||||
for (int i = 0, max = (lives < 5) ? 5 : lives; i < max; i++) {
|
||||
if (i < lives) {
|
||||
GUI::DrawImage(Textures::GetLives(), 5 + i * 13, 5, tex_size, tex_size);
|
||||
}
|
||||
else {
|
||||
GUI::DrawImageTint(Textures::GetLives(), 5 + i * 13, 5, tex_size, tex_size, G2D_RGBA(50, 50, 50, 200));
|
||||
}
|
||||
}
|
||||
|
||||
GUI::FontSetStyle(1.0f, G2D_RGBA(255, 255, 255, 255), INTRAFONT_ALIGN_LEFT);
|
||||
GUI::DrawText((472 - GUI::GetTextWidth(stage_str)), 17, stage_str);
|
||||
GUI::DrawText((472 - GUI::GetTextWidth(row_str)), 35, row_str);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
x = 138;
|
||||
|
||||
for (int j = 0; j < 4; j++) {
|
||||
if (selection == (i * 4 + j)) {
|
||||
GUI::DrawRect(x - 1, y - 1, 52, 52, G2D_RGBA(255, 255, 255, 255));
|
||||
}
|
||||
|
||||
GUI::DrawRect(x, y, 50, 50, (pattern[i * 4 + j]) ? G2D_RGBA(color[0] - diff, color[1] - diff, color[2] - diff, 255) : G2D_RGBA(color[0], color[1], color[2], 255));
|
||||
x += 52;
|
||||
}
|
||||
|
||||
y += 52;
|
||||
}
|
||||
|
||||
if (timer) {
|
||||
GUI::DrawRect(0, 257, time_left, 15, (time_left > 100) ? G2D_RGBA(0, 255, 0, 255) : G2D_RGBA(255, 0, 0, 255));
|
||||
}
|
||||
|
||||
if (paused) {
|
||||
GUI::DrawRect(0, 0, 480, 282, G2D_RGBA(128, 128, 128, 130));
|
||||
|
||||
GUI::FontSetStyle(1.0f, G2D_RGBA(200, 0, 0, 255), INTRAFONT_ALIGN_LEFT);
|
||||
GUI::DrawText((472 - GUI::GetTextWidth("Paused")) / 2, 100, "Paused");
|
||||
|
||||
GUI::FontSetStyle(1.0f, G2D_RGBA(0, 0, 0, 255), INTRAFONT_ALIGN_LEFT);
|
||||
GUI::DrawText((472 - GUI::GetTextWidth("Press start to continue")) / 2, 130, "Press start to continue");
|
||||
GUI::DrawText((472 - GUI::GetTextWidth(PSP_CTRL_CANCEL == PSP_CTRL_CIRCLE? "Press O button to exit" : "Press X button to exit")) / 2,
|
||||
150, PSP_CTRL_CANCEL == PSP_CTRL_CIRCLE? "Press O button to exit" : "Press X button to exit");
|
||||
|
||||
if (Utils::IsButtonPressed(PSP_CTRL_CANCEL)) {
|
||||
lives = 0;
|
||||
}
|
||||
}
|
||||
|
||||
g2dFlip(G2D_VSYNC);
|
||||
|
||||
if (timer) {
|
||||
if (!paused) {
|
||||
if (--time_left == 0 && lives > 0) {
|
||||
Audio::PlayNopeWav();
|
||||
time_left = 480;
|
||||
lives--;
|
||||
row = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (win) {
|
||||
if (++stages % 10 == 0 && lives < 10) {
|
||||
lives++;
|
||||
}
|
||||
|
||||
Game::Update();
|
||||
max_stages = (stages >= max_stages) ? stages : max_stages;
|
||||
row++;
|
||||
|
||||
if (timer == true) {
|
||||
Game::Begin(true);
|
||||
}
|
||||
else {
|
||||
Game::Begin(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void End(void) {
|
||||
char stages_str[26], score_str[20], matches_str[20];
|
||||
|
||||
Game::SaveHighscore();
|
||||
std::snprintf(stages_str, 24, "You scored %d!", stages);
|
||||
std::snprintf(score_str, 20, "Best score: %d", Game::GetHighscore());
|
||||
std::snprintf(matches_str, 20, "Games played: %d", matches);
|
||||
Audio::PlayGameOverWav();
|
||||
|
||||
while(true) {
|
||||
Utils::ReadControls();
|
||||
|
||||
if (Utils::IsButtonPressed(PSP_CTRL_ENTER)) {
|
||||
break;
|
||||
}
|
||||
|
||||
g2dClear(WHITE);
|
||||
GUI::FontSetStyle(1.5f, G2D_RGBA(200, 0, 0, 255), INTRAFONT_ALIGN_LEFT);
|
||||
|
||||
GUI::DrawText((480 - GUI::GetTextWidth("GAME OVER")) / 2, 40, "GAME OVER");
|
||||
|
||||
GUI::FontSetStyle(1.0f, G2D_RGBA(128, 128, 128, 255), INTRAFONT_ALIGN_LEFT);
|
||||
GUI::DrawText((480 - GUI::GetTextWidth(stages_str)) / 2, 80, stages_str);
|
||||
GUI::DrawText((480 - GUI::GetTextWidth(score_str)) / 2, 100, score_str);
|
||||
GUI::DrawText((480 - GUI::GetTextWidth(matches_str)) / 2, 120, matches_str);
|
||||
GUI::DrawText((480 - GUI::GetTextWidth("Press X to try again")) / 2, 140, "Press X to try again");
|
||||
|
||||
g2dFlip(G2D_VSYNC);
|
||||
}
|
||||
}
|
||||
|
||||
void Loop(void) {
|
||||
srand(time(nullptr));
|
||||
Game::Init();
|
||||
matches = 0;
|
||||
max_stages = 0;
|
||||
|
||||
while(g_running) {
|
||||
int ctrl = Utils::ReadControls();
|
||||
|
||||
if (Utils::IsButtonPressed(PSP_CTRL_ENTER)) {
|
||||
Game::Begin(true);
|
||||
matches++;
|
||||
Game::End();
|
||||
Game::Init();
|
||||
}
|
||||
|
||||
if (Utils::IsButtonPressed(PSP_CTRL_SQUARE)) {
|
||||
Game::Begin(false);
|
||||
matches++;
|
||||
Game::End();
|
||||
Game::Init();
|
||||
}
|
||||
|
||||
Game::MainMenu();
|
||||
|
||||
if (Utils::IsButtonPressed(PSP_CTRL_START)) {
|
||||
g_running = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
50
source/gui.cpp
Normal file
50
source/gui.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
#include "gui.hpp"
|
||||
|
||||
intraFont *g_font;
|
||||
|
||||
namespace GUI {
|
||||
void DrawRect(float x, float y, float width, float height, g2dColor colour) {
|
||||
g2dBeginRects(nullptr); {
|
||||
g2dSetColor(colour);
|
||||
g2dSetScaleWH(width, height);
|
||||
g2dSetCoordXY(x, y);
|
||||
g2dAdd();
|
||||
}
|
||||
g2dEnd();
|
||||
}
|
||||
|
||||
void DrawImage(g2dTexture *tex, float x, float y, float w, float h) {
|
||||
g2dBeginRects(tex); {
|
||||
g2dSetScaleWH(w, h);
|
||||
g2dSetCoordXY(x, y);
|
||||
g2dAdd();
|
||||
}
|
||||
g2dEnd();
|
||||
}
|
||||
|
||||
void DrawImageTint(g2dTexture *tex, float x, float y, float w, float h, g2dColor colour) {
|
||||
g2dBeginRects(tex); {
|
||||
g2dSetColor(colour);
|
||||
g2dSetScaleWH(w, h);
|
||||
g2dSetCoordXY(x, y);
|
||||
g2dAdd();
|
||||
}
|
||||
g2dEnd();
|
||||
}
|
||||
|
||||
void FontSetStyle(float size, unsigned int colour, unsigned int options) {
|
||||
intraFontSetStyle(g_font, size, colour, G2D_RGBA(0, 0, 0, 0), 0.f, options);
|
||||
}
|
||||
|
||||
float GetTextHeight(void) {
|
||||
return g_font->advancey * g_font->size / 4.f + 2.f;
|
||||
}
|
||||
|
||||
float GetTextWidth(const std::string &text) {
|
||||
return intraFontMeasureText(g_font, text.c_str());
|
||||
}
|
||||
|
||||
float DrawText(float x, float y, const std::string &text) {
|
||||
return intraFontPrintf(g_font, x, y, text.c_str());
|
||||
}
|
||||
}
|
74
source/main.cpp
Normal file
74
source/main.cpp
Normal file
@ -0,0 +1,74 @@
|
||||
#include <pspkernel.h>
|
||||
|
||||
#include "audio.hpp"
|
||||
#include "game.hpp"
|
||||
#include "gui.hpp"
|
||||
#include "textures.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
PSP_MODULE_INFO("PSPickr", 0, VERSION_MAJOR, VERSION_MINOR);
|
||||
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU);
|
||||
|
||||
bool g_running = true;
|
||||
|
||||
namespace Services {
|
||||
int Init(void) {
|
||||
int ret = 0;
|
||||
|
||||
sceCtrlSetSamplingCycle(0);
|
||||
sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG);
|
||||
|
||||
if (R_FAILED(ret = intraFontInit())) {
|
||||
pspDebugScreenPrintf("intraFontInit failed: 0x%08x\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Load audio, font and textures.
|
||||
Audio::Init();
|
||||
Audio::InitGameOverWav();
|
||||
Audio::InitNopeWav();
|
||||
g_font = intraFontLoad("flash0:/font/ltn8.pgf", INTRAFONT_CACHE_ALL);
|
||||
Textures::Init();
|
||||
|
||||
PSP_CTRL_ENTER = Utils::GetEnterButton();
|
||||
PSP_CTRL_CANCEL = Utils::GetCancelButton();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Exit(void) {
|
||||
Textures::Exit();
|
||||
intraFontUnload(g_font);
|
||||
Audio::Exit();
|
||||
sceKernelExitGame();
|
||||
}
|
||||
|
||||
static int ExitCallback(int arg1, int arg2, void *common) {
|
||||
g_running = false;
|
||||
Services::Exit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int CallbackThread(SceSize args, void *argp) {
|
||||
int callback = 0;
|
||||
callback = sceKernelCreateCallback("ExitCallback", Services::ExitCallback, nullptr);
|
||||
sceKernelRegisterExitCallback(callback);
|
||||
sceKernelSleepThreadCB();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SetupCallbacks(void) {
|
||||
int thread = 0;
|
||||
|
||||
if (R_SUCCEEDED(thread = sceKernelCreateThread("CallbackThread", Services::CallbackThread, 0x11, 0xFA0, 0, nullptr)))
|
||||
sceKernelStartThread(thread, 0, 0);
|
||||
|
||||
return thread;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
Services::SetupCallbacks();
|
||||
Services::Init();
|
||||
Game::Loop();
|
||||
Services::Exit();
|
||||
}
|
57
source/textures.cpp
Normal file
57
source/textures.cpp
Normal file
@ -0,0 +1,57 @@
|
||||
#include <cstring>
|
||||
#include <png.h>
|
||||
#include <pspdebug.h>
|
||||
|
||||
#include "textures.hpp"
|
||||
|
||||
extern unsigned char lives_png_start[];
|
||||
extern unsigned int lives_png_size;
|
||||
|
||||
namespace Textures {
|
||||
static g2dTexture *lives_tex;
|
||||
|
||||
g2dTexture *LoadImageBufferPNG(unsigned char *data, int size) {
|
||||
g2dTexture *tex = nullptr;
|
||||
png_image image;
|
||||
std::memset(&image, 0, (sizeof image));
|
||||
image.version = PNG_IMAGE_VERSION;
|
||||
|
||||
if (png_image_begin_read_from_memory(&image, data, size) != 0) {
|
||||
png_bytep buffer;
|
||||
image.format = PNG_FORMAT_RGBA;
|
||||
buffer = new png_byte[PNG_IMAGE_SIZE(image)];
|
||||
|
||||
if (buffer != nullptr && png_image_finish_read(&image, nullptr, buffer, 0, nullptr) != 0) {
|
||||
tex = g2dTexLoad(buffer, image.width, image.height, G2D_SWIZZLE);
|
||||
delete[] buffer;
|
||||
png_image_free(&image);
|
||||
}
|
||||
else {
|
||||
if (buffer == nullptr) {
|
||||
pspDebugScreenPrintf("png_byte buffer: returned nullptr\n");
|
||||
png_image_free(&image);
|
||||
}
|
||||
else {
|
||||
pspDebugScreenPrintf("png_image_finish_read failed: %s\n", image.message);
|
||||
delete[] buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
pspDebugScreenPrintf("png_image_begin_read_from_memory failed: %s\n", image.message);
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
void Init(void) {
|
||||
lives_tex = Textures::LoadImageBufferPNG(lives_png_start, lives_png_size);
|
||||
}
|
||||
|
||||
void Exit(void) {
|
||||
g2dTexFree(&lives_tex);
|
||||
}
|
||||
|
||||
g2dTexture *GetLives(void) {
|
||||
return lives_tex;
|
||||
}
|
||||
}
|
168
source/utils.cpp
Normal file
168
source/utils.cpp
Normal file
@ -0,0 +1,168 @@
|
||||
#include <cstring>
|
||||
#include <pspkernel.h>
|
||||
#include <pspreg.h>
|
||||
#include <psputility_sysparam.h>
|
||||
|
||||
#include "utils.hpp"
|
||||
|
||||
enum PspCtrlButtons PSP_CTRL_ENTER, PSP_CTRL_CANCEL;
|
||||
|
||||
namespace Utils {
|
||||
constexpr unsigned int CTRL_DEADZONE_DELAY = 500000;
|
||||
constexpr unsigned int CTRL_DELAY = 100000;
|
||||
|
||||
static SceCtrlData pad, prev_pad;
|
||||
static unsigned int last_button = 0;
|
||||
static int last_button_tick = 0, deadzone_tick = 0;
|
||||
|
||||
void SetBounds(int &set, int min, int max) {
|
||||
if (set > max)
|
||||
set = min;
|
||||
else if (set < min)
|
||||
set = max;
|
||||
}
|
||||
|
||||
static int GetRegistryValue(const char *dir, const char *name, unsigned int *value) {
|
||||
int ret = 0;
|
||||
struct RegParam reg_param;
|
||||
REGHANDLE reg_handle = 0, reg_handle_cat = 0, reg_handle_key = 0;
|
||||
unsigned int type = 0, size = 0;
|
||||
|
||||
std::memset(®_param, 0, sizeof(RegParam));
|
||||
reg_param.regtype = 1;
|
||||
reg_param.namelen = std::strlen("/system");
|
||||
reg_param.unk2 = 1;
|
||||
reg_param.unk3 = 1;
|
||||
std::strcpy(reg_param.name, "/system");
|
||||
|
||||
if (R_FAILED(ret = sceRegOpenRegistry(®_param, 2, ®_handle))) {
|
||||
pspDebugScreenPrintf("sceRegOpenRegistry() failed: 0x%08x\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (R_FAILED(ret = sceRegOpenCategory(reg_handle, dir, 2, ®_handle_cat))) {
|
||||
sceRegCloseRegistry(reg_handle);
|
||||
pspDebugScreenPrintf("sceRegOpenCategory() failed: 0x%08x\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (R_FAILED(ret = sceRegGetKeyInfo(reg_handle_cat, name, ®_handle_key, &type, &size))) {
|
||||
sceRegCloseCategory(reg_handle_cat);
|
||||
sceRegCloseRegistry(reg_handle);
|
||||
pspDebugScreenPrintf("sceRegGetKeyInfo() failed: 0x%08x\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (R_FAILED(ret = sceRegGetKeyValue(reg_handle_cat, reg_handle_key, value, 4))) {
|
||||
sceRegCloseCategory(reg_handle_cat);
|
||||
sceRegCloseRegistry(reg_handle);
|
||||
pspDebugScreenPrintf("sceRegGetKeyValue() failed: 0x%08x\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (R_FAILED(ret = sceRegFlushCategory(reg_handle_cat))) {
|
||||
sceRegCloseCategory(reg_handle_cat);
|
||||
sceRegCloseRegistry(reg_handle);
|
||||
pspDebugScreenPrintf("sceRegFlushCategory() failed: 0x%08x\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (R_FAILED(ret = sceRegCloseCategory(reg_handle_cat))) {
|
||||
sceRegCloseRegistry(reg_handle);
|
||||
pspDebugScreenPrintf("sceRegCloseCategory() failed: 0x%08x\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (R_FAILED(ret = sceRegFlushRegistry(reg_handle))) {
|
||||
sceRegCloseRegistry(reg_handle);
|
||||
pspDebugScreenPrintf("sceRegFlushRegistry() failed: 0x%08x\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (R_FAILED(ret = sceRegCloseRegistry(reg_handle))) {
|
||||
pspDebugScreenPrintf("sceRegFlushRegistry() failed: 0x%08x\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ReadControls(void) {
|
||||
prev_pad = pad;
|
||||
sceCtrlReadBufferPositive(&pad, 1);
|
||||
|
||||
if (pad.Buttons == last_button) {
|
||||
if (pad.TimeStamp - deadzone_tick < CTRL_DEADZONE_DELAY)
|
||||
return 0;
|
||||
|
||||
if (pad.TimeStamp - last_button_tick < CTRL_DELAY)
|
||||
return 0;
|
||||
|
||||
last_button_tick = pad.TimeStamp;
|
||||
return last_button;
|
||||
}
|
||||
|
||||
last_button = pad.Buttons;
|
||||
deadzone_tick = last_button_tick = pad.TimeStamp;
|
||||
return last_button;
|
||||
}
|
||||
|
||||
int IsButtonPressed(enum PspCtrlButtons buttons) {
|
||||
return ((pad.Buttons & buttons) == buttons) && ((prev_pad.Buttons & buttons) != buttons);
|
||||
}
|
||||
|
||||
int IsButtonHeld(enum PspCtrlButtons buttons) {
|
||||
return pad.Buttons & buttons;
|
||||
}
|
||||
|
||||
enum PspCtrlButtons GetEnterButton(void) {
|
||||
int ret = 0, button = -1;
|
||||
|
||||
if (R_FAILED(ret = sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_UNKNOWN, &button))) {
|
||||
pspDebugScreenPrintf("sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_UNKNOWN) failed: 0x%08x\n", ret);
|
||||
|
||||
unsigned int reg_button = -1;
|
||||
if (R_SUCCEEDED(Utils::GetRegistryValue("/CONFIG/SYSTEM/XMB", "button_assign", ®_button))) {
|
||||
if (reg_button == 0)
|
||||
return PSP_CTRL_CIRCLE;
|
||||
|
||||
return PSP_CTRL_CROSS;
|
||||
}
|
||||
}
|
||||
|
||||
if (button == 0)
|
||||
return PSP_CTRL_CIRCLE;
|
||||
|
||||
return PSP_CTRL_CROSS; // By default return PSP_CTRL_CROSS
|
||||
}
|
||||
|
||||
// Basically the opposite of GetEnterButton()
|
||||
enum PspCtrlButtons GetCancelButton(void) {
|
||||
int ret = 0, button = -1;
|
||||
|
||||
if (R_FAILED(ret = sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_UNKNOWN, &button))) {
|
||||
pspDebugScreenPrintf("sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_UNKNOWN) failed: 0x%08x\n", ret);
|
||||
|
||||
unsigned int reg_button = -1;
|
||||
if (R_SUCCEEDED(Utils::GetRegistryValue("/CONFIG/SYSTEM/XMB", "button_assign", ®_button))) {
|
||||
if (reg_button == 0)
|
||||
return PSP_CTRL_CROSS;
|
||||
|
||||
return PSP_CTRL_CIRCLE;
|
||||
}
|
||||
}
|
||||
|
||||
if (button == 0)
|
||||
return PSP_CTRL_CROSS;
|
||||
|
||||
return PSP_CTRL_CIRCLE; // By default return PSP_CTRL_CIRCLE
|
||||
}
|
||||
|
||||
float GetAnalogX(void) {
|
||||
return ((static_cast<float>(pad.Lx - 122.5f)) / 122.5f);
|
||||
}
|
||||
|
||||
float GetAnalogY(void) {
|
||||
return ((static_cast<float>(pad.Ly - 122.5f)) / 122.5f);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user