1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4
5 #include <pspkernel.h>
6 #include <psppower.h>
7 #include <pspdisplay.h>
8 #include <pspctrl.h>
9 #include <psprtc.h>
10 #include <pspaudiolib.h>
11 #include <pspaudio.h>
12
13 PSP_MODULE_INFO("OpenLara", 0, 1, 1);
14 PSP_HEAP_SIZE_KB(20480);
15 PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_USER | PSP_THREAD_ATTR_VFPU | PSP_THREAD_ATTR_NO_FILLSTACK);
16
17 #include "game.h"
18
19 #define BUF_WIDTH (512)
20 #define SCR_WIDTH (480)
21 #define SCR_HEIGHT (272)
22
exitCallback(int arg1,int arg2,void * common)23 int exitCallback(int arg1, int arg2, void *common) {
24 Core::quit();
25 return 0;
26 }
27
callbackThread(SceSize args,void * argp)28 int callbackThread(SceSize args, void *argp) {
29 int cbid = sceKernelCreateCallback("Exit Callback", exitCallback, NULL);
30 sceKernelRegisterExitCallback(cbid);
31 sceKernelSleepThreadCB();
32 return 0;
33 }
34
setupCallbacks(void)35 int setupCallbacks(void) {
36 int thid = sceKernelCreateThread("update_thread", callbackThread, 0x11, 0xFA0, 0, 0);
37 sceKernelStartThread(thid, 0, 0);
38 return thid;
39 }
40
41
42 // multi-threading
osMutexInit()43 void* osMutexInit() {
44 SceUID *mutex = new SceUID();
45 *mutex = sceKernelCreateSema(NULL, 0, 1, 1, 0);
46 return mutex;
47 }
48
osMutexFree(void * obj)49 void osMutexFree(void *obj) {
50 sceKernelDeleteSema(*(SceUID*)obj);
51 delete (SceUID*)obj;
52 }
53
osMutexLock(void * obj)54 void osMutexLock(void *obj) {
55 sceKernelWaitSema(*(SceUID*)obj, 1, NULL);
56 }
57
osMutexUnlock(void * obj)58 void osMutexUnlock(void *obj) {
59 sceKernelSignalSema(*(SceUID*)obj, 1);
60 }
61
osRWLockInit()62 void* osRWLockInit() {
63 return osMutexInit();
64 }
65
osRWLockFree(void * obj)66 void osRWLockFree(void *obj) {
67 osMutexFree(obj);
68 }
69
osRWLockRead(void * obj)70 void osRWLockRead(void *obj) {
71 osMutexLock(obj);
72 }
73
osRWUnlockRead(void * obj)74 void osRWUnlockRead(void *obj) {
75 osMutexUnlock(obj);
76 }
77
osRWLockWrite(void * obj)78 void osRWLockWrite(void *obj) {
79 osMutexLock(obj);
80 }
81
osRWUnlockWrite(void * obj)82 void osRWUnlockWrite(void *obj) {
83 osMutexUnlock(obj);
84 }
85
86 // timing
87 int osStartTime = 0;
88 int osTimerFreq;
89
osGetTimeMS()90 int osGetTimeMS() {
91 u64 time;
92 sceRtcGetCurrentTick(&time);
93 return int(time * 1000 / osTimerFreq - osStartTime);
94 }
95
96 // input
osJoyReady(int index)97 bool osJoyReady(int index) {
98 return index == 0;
99 }
100
osJoyVibrate(int index,float L,float R)101 void osJoyVibrate(int index, float L, float R) {
102 //
103 }
104
joyInit()105 void joyInit() {
106 sceCtrlSetSamplingCycle(0);
107 sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG);
108 }
109
joyUpdate()110 void joyUpdate() {
111 SceCtrlData pad;
112 sceCtrlReadBufferPositive(&pad, 1);
113
114 Input::setJoyDown(0, jkUp, (pad.Buttons & PSP_CTRL_UP));
115 Input::setJoyDown(0, jkDown, (pad.Buttons & PSP_CTRL_DOWN));
116 Input::setJoyDown(0, jkLeft, (pad.Buttons & PSP_CTRL_LEFT));
117 Input::setJoyDown(0, jkRight, (pad.Buttons & PSP_CTRL_RIGHT));
118 Input::setJoyDown(0, jkA, (pad.Buttons & PSP_CTRL_CROSS));
119 Input::setJoyDown(0, jkB, (pad.Buttons & PSP_CTRL_CIRCLE));
120 Input::setJoyDown(0, jkX, (pad.Buttons & PSP_CTRL_SQUARE));
121 Input::setJoyDown(0, jkY, (pad.Buttons & PSP_CTRL_TRIANGLE));
122 Input::setJoyDown(0, jkLB, (pad.Buttons & PSP_CTRL_LTRIGGER));
123 Input::setJoyDown(0, jkRB, (pad.Buttons & PSP_CTRL_RTRIGGER));
124 Input::setJoyDown(0, jkStart, (pad.Buttons & PSP_CTRL_START));
125 Input::setJoyDown(0, jkSelect, (pad.Buttons & PSP_CTRL_SELECT));
126
127 vec2 stick = vec2(float(pad.Lx), float(pad.Ly)) / 128.0f - 1.0f;
128 if (fabsf(stick.x) < 0.2f && fabsf(stick.y) < 0.2f)
129 stick = vec2(0.0f);
130 Input::setJoyPos(0, jkL, stick);
131 }
132
sndFill(void * buf,unsigned int length,void * userdata)133 void sndFill(void* buf, unsigned int length, void *userdata) {
134 Sound::fill((Sound::Frame*)buf, length);
135 }
136
sndInit()137 void sndInit() {
138 pspAudioInit();
139 pspAudioSetChannelCallback(0, sndFill, NULL);
140 }
141
main()142 int main() {
143 cacheDir[0] = saveDir[0] = contentDir[0] = 0;
144
145 scePowerSetClockFrequency(333, 333, 166);
146 setupCallbacks();
147
148 sceGuInit();
149
150 GAPI::beginCmdBuf();
151
152 sceGuDrawBuffer(GU_PSM_5650, (void*)0, BUF_WIDTH);
153 sceGuDispBuffer(SCR_WIDTH, SCR_HEIGHT, (void*)(BUF_WIDTH * SCR_HEIGHT * 2), BUF_WIDTH);
154 sceGuDepthBuffer((void*)(BUF_WIDTH * SCR_HEIGHT * 2 * 2), BUF_WIDTH);
155
156 sceGuScissor(0, 0, SCR_WIDTH, SCR_HEIGHT);
157 sceGuEnable(GU_SCISSOR_TEST);
158
159 sndInit();
160 joyInit();
161
162 osTimerFreq = sceRtcGetTickResolution();
163 osStartTime = Core::getTime();
164
165 Game::init();
166
167 GAPI::submitCmdBuf();
168
169 sceDisplayWaitVblankStart();
170 sceGuDisplay(GU_TRUE);
171
172 GAPI::curBackBuffer = 0;
173
174 while (!Core::isQuit) {
175 GAPI::beginCmdBuf();
176
177 joyUpdate();
178 Game::update();
179 Game::render();
180 GAPI::submitCmdBuf();
181 Core::waitVBlank();
182 GAPI::curBackBuffer = sceGuSwapBuffers();
183 }
184
185 Game::deinit();
186
187 sceGuTerm();
188 sceKernelExitGame();
189
190 return 0;
191 }