4 This is Pokitto implementation of the game front end, using the official
7 by Miloslav Ciz (drummyfish), 2019
9 Released under CC0 1.0 (https://creativecommons.org/publicdomain/zero/1.0/)
10 plus a waiver of all other intellectual property. The goal of this work is to
11 be and remain completely in the public domain forever, available for any use
15 #define JOYHAT // compiles the version for Pokitto with joystick hat
19 #define SFG_LOG(s) puts(s);
20 #define SFG_CPU_LOAD(x) printf("CPU: %d\n",x);
26 #define SFG_DIMINISH_SPRITES 1
27 #define SFG_RAYCASTING_MAX_HITS 6
30 #define SFG_DIMINISH_SPRITES 0
31 #define SFG_RAYCASTING_MAX_HITS 5
34 #define SFG_CAN_EXIT 0
35 #define SFG_PLAYER_TURN_SPEED 135
38 #define SFG_SCREEN_RESOLUTION_X 110
39 #define SFG_SCREEN_RESOLUTION_Y 88
41 #define SFG_SCREEN_RESOLUTION_X 88
42 #define SFG_SCREEN_RESOLUTION_Y 110
44 #define SFG_FOV_VERTICAL 350
45 #define SFG_FOV_HORIZONTAL 210
47 #include "JoyHat/JoyHat.h"
50 uint16_t rumbleCooldown
= 0;
51 uint16_t axisThreshold1
, axisThreshold2
;
54 #define SFG_RESOLUTION_SCALEDOWN 1
55 #define SFG_DITHERED_SHADOW 0
56 #define SFG_FOG_DIMINISH_STEP 2048
57 #define SFG_RAYCASTING_MAX_STEPS 20
58 #define SFG_RAYCASTING_SUBSAMPLE 2
63 #include "../PokittoLib/Pokitto/POKITTO_HW/clock_11u6x.h"
64 #include "../PokittoLib/Pokitto/POKITTO_HW/timer_11u6x.h"
66 #include "../PokittoLib/Pokitto/Pokitto.h"
67 #include "PokittoCookie.h"
69 class SaveCookie
: public Pokitto::Cookie
72 uint8_t data
[SFG_SAVE_SIZE
];
77 Pokitto::Core pokitto
;
79 uint8_t *pokittoScreen
;
81 void SFG_setPixel(uint16_t x
, uint16_t y
, uint8_t colorIndex
)
84 pokittoScreen
[y
* SFG_SCREEN_RESOLUTION_X
+ x
] = colorIndex
;
86 pokittoScreen
[x
* SFG_SCREEN_RESOLUTION_Y
+ (SFG_SCREEN_RESOLUTION_Y
- 1 - y
)]
91 uint32_t SFG_getTimeMs()
93 return pokitto
.getTime();
96 void SFG_sleepMs(uint16_t timeMs
)
100 int8_t SFG_keyPressed(uint8_t key
)
105 case SFG_KEY_UP
: return joy
.JoyX() < axisThreshold1
; break;
106 case SFG_KEY_DOWN
: return joy
.JoyX() > axisThreshold2
; break;
107 case SFG_KEY_RIGHT
: return joy
.JoyY() > axisThreshold2
; break;
108 case SFG_KEY_LEFT
: return joy
.JoyY() < axisThreshold1
; break;
109 case SFG_KEY_JUMP
: return pokitto
.rightBtn(); break;
110 case SFG_KEY_STRAFE_RIGHT
: return pokitto
.downBtn(); break;
111 case SFG_KEY_STRAFE_LEFT
: return pokitto
.upBtn(); break;
112 case SFG_KEY_MAP
: return pokitto
.leftBtn(); break;
113 case SFG_KEY_PREVIOUS_WEAPON
: return joy
.Button1(); break;
114 case SFG_KEY_NEXT_WEAPON
: return joy
.Button2(); break;
116 case SFG_KEY_UP
: return pokitto
.upBtn(); break;
117 case SFG_KEY_DOWN
: return pokitto
.downBtn(); break;
118 case SFG_KEY_RIGHT
: return pokitto
.rightBtn(); break;
119 case SFG_KEY_LEFT
: return pokitto
.leftBtn(); break;
122 case SFG_KEY_A
: return pokitto
.aBtn(); break;
123 case SFG_KEY_B
: return pokitto
.bBtn(); break;
124 case SFG_KEY_C
: return pokitto
.cBtn(); break;
125 default: return 0; break;
129 void SFG_getMouseOffset(int16_t *x
, int16_t *y
)
133 uint8_t audioBuff
[SFG_SFX_SAMPLE_COUNT
];
134 uint16_t audioPos
= 0;
138 void SFG_setMusic(uint8_t value
)
142 case SFG_MUSIC_TURN_ON
: musicOn
= 1; break;
143 case SFG_MUSIC_TURN_OFF
: musicOn
= 0; break;
146 /* Skipping a track takes some time, so turn off music for a while
147 (otherwise noise can be heard). */
148 uint8_t music
= musicOn
;
150 SFG_nextMusicTrack();
158 static inline uint8_t mixSamples(uint8_t sample1
, uint8_t sample2
)
160 return (sample1
>> 1) + (sample2
>> 1);
163 void onTimer() // for sound
165 if (Chip_TIMER_MatchPending(LPC_TIMER32_0
, 1))
167 Chip_TIMER_ClearMatch(LPC_TIMER32_0
, 1);
171 mixSamples(audioBuff
[audioPos
],SFG_getNextMusicSample() / 2) :
175 audioBuff
[audioPos
] = 127;
177 audioPos
= (audioPos
+ 1) % SFG_SFX_SAMPLE_COUNT
;
181 void timerInit(uint32_t samplingRate
)
183 Chip_TIMER_Init(LPC_TIMER32_0
);
184 Chip_TIMER_Reset(LPC_TIMER32_0
);
185 Chip_TIMER_MatchEnableInt(LPC_TIMER32_0
, 1);
186 Chip_TIMER_SetMatch(LPC_TIMER32_0
, 1,
187 (Chip_Clock_GetSystemClockRate() / samplingRate
));
188 Chip_TIMER_ResetOnMatchEnable(LPC_TIMER32_0
, 1);
189 Chip_TIMER_Enable(LPC_TIMER32_0
);
191 #define weirdNumber ((IRQn_Type) 18)
192 NVIC_ClearPendingIRQ(weirdNumber
);
193 NVIC_SetVector(weirdNumber
, (uint32_t) &onTimer
);
194 NVIC_EnableIRQ(weirdNumber
);
198 void SFG_save(uint8_t data
[SFG_SAVE_SIZE
])
200 for (uint8_t i
= 0; i
< SFG_SAVE_SIZE
; ++i
)
201 save
.data
[i
] = data
[i
];
205 /* ^ This causes sound to stop as it writes something to timer32, we need to
211 void SFG_processEvent(uint8_t event
, uint8_t data
)
216 case SFG_EVENT_VIBRATE
:
217 if (rumbleCooldown
== 0)
229 uint8_t SFG_load(uint8_t data
[SFG_SAVE_SIZE
])
231 for (uint8_t i
= 0; i
< SFG_SAVE_SIZE
; ++i
)
232 data
[i
] = save
.data
[i
];
237 void SFG_playSound(uint8_t soundIndex
, uint8_t volume
)
239 uint8_t volumeShift
= 7 - volume
/ 32;
240 uint16_t baseLevel
= 128 - (128 >> volumeShift
);
242 uint16_t pos
= audioPos
;
244 for (int i
= 0; i
< SFG_SFX_SAMPLE_COUNT
; ++i
)
246 audioBuff
[pos
] = mixSamples(audioBuff
[pos
],baseLevel
+
247 (SFG_GET_SFX_SAMPLE(soundIndex
,i
) >> volumeShift
));
249 pos
= (pos
< SFG_SFX_SAMPLE_COUNT
- 1) ? (pos
+ 1) : 0;
255 save
.begin("ANARCH",sizeof(save
),(char*) &save
);
260 axisThreshold1
= joy
.joyScale
/ 4;
261 axisThreshold2
= joy
.joyScale
- axisThreshold1
;
264 uint8_t allZeros
= 1;
266 for (uint8_t i
= 0; i
< SFG_SAVE_SIZE
; ++i
)
267 if (save
.data
[i
] != 0)
273 if (allZeros
) // 1st time save?
275 SFG_createDefaultSaveData(save
.data
);
281 for (uint16_t i
= 0; i
< SFG_SFX_SAMPLE_COUNT
; ++i
)
284 pokitto
.setFrameRate(255);
285 pokitto
.display
.setFont(fontTiny
);
286 pokitto
.display
.persistence
= 1;
287 pokitto
.display
.setInvisibleColor(-1);
288 pokitto
.display
.load565Palette(paletteRGB565
);
290 pokittoScreen
= pokitto
.display
.screenbuffer
;
294 while (pokitto
.isRunning())
296 if (pokitto
.update())
300 if (rumbleCooldown
> 0)
304 if (SFG_game
.state
== SFG_GAME_STATE_MENU
&&
305 SFG_game
.keyStates
[SFG_KEY_LEFT
] == 255 &&
306 SFG_game
.keyStates
[SFG_KEY_RIGHT
] == 255 &&
307 SFG_game
.keyStates
[SFG_KEY_B
] == 255)
309 // holding L+R+B in menu will erase all saved data
316 pokitto
.display
.setCursor(0,0);
317 pokitto
.display
.print(pokitto
.fps_counter
);