问题描述
大家好!最近在研究一些PSP编程,尝试用pspdisplay.h库做一个小游戏。游戏非常基础,目前只有一个红色方块四处移动,屏幕上会出现一些十字形的东西。一切都很顺利,直到我注意到根据我更新和交换帧缓冲区的频率,屏幕上的某个地方会出现一个区域?其中所有输出的对象都倾向于闪烁。该区域的宽度均为 480 像素,高度为 10-20 像素。该区域在 Y 轴上的位置取决于帧缓冲区更新的频率。如何解决?是什么原因造成的?为什么区域位置取决于帧缓冲区的更新频率? P.S 如果你想看它的视频,这里是我的 reddit 问题的链接,关于固定到它的视频的相同问题:https://www.reddit.com/r/PSP/comments/mccjp4/been_studying_some_psp_programming_recently_and/?utm_source=share&utm_medium=web2x&context=3
要重现此问题,您需要 PSP 3000、psptoolchain 和 pspsdk。
我有一个小的 Cell 结构,它保存了 8x8 正方形左上角的坐标、颜色和方向,即上、下、左、右或无:
struct Cell{
uint32_t color;
int x;
int y;
directions direction;
bool occupied;
inline Cell();
inline Cell(uint32_t,int,bool,directions);
~Cell();
};
之后我初始化 PSP 屏幕并控制并启动一个循环,该循环一直运行直到用户按下 START 按钮。在控制检查之后是时间检查,如果所需的毫秒数已经过去,则将正方形沿其方向移动一个像素。
while(running){
running = is_running();
sceCtrlPeekBufferPositive(&button_input,1);
if(button_input.Buttons != 0){
if(button_input.Buttons & PSP_CTRL_UP){
cl.direction = directions::up;
}
if(button_input.Buttons & PSP_CTRL_DOWN){
cl.direction = directions::down;
}
if(button_input.Buttons & PSP_CTRL_LEFT){
cl.direction = directions::left;
}
if(button_input.Buttons & PSP_CTRL_RIGHT){
cl.direction = directions::right;
}
if(button_input.Buttons & PSP_CTRL_START){
running = 0;
}
}
if(current_timestamp() - lmt >= 40){
clear(0xff000);
switch(cl.direction){
case directions::up:
cl.y--;
break;
case directions::down:
cl.y++;
break;
case directions::left:
cl.x--;
break;
case directions::none:
break;
case directions::right:
cl.x++;
}
}
draw_cell(cl);
swap_buffers();
scedisplayWaitVblank();
lmt = current_timestamp();
}
draw_cell(Cell cl) 函数只是将一个单元格写入绘制缓冲区。 swap_buffers() 函数通过将我的方块输出到屏幕来交换绘制缓冲区和显示缓冲区。 clear 函数只是用一种颜色填充绘制缓冲区,作为它的参数。
void draw_cell(Cell cl){
for(int y = cl.y; y < cl.y+8; y++){
for(int x = cl.x; x < cl.x+8; x++){
draw_buffer[x + y * 512] = cl.color;
}
}
}
void clear(uint32_t color){
for(int i = 0; i < 512 * 272; i++){
draw_buffer[i] = color;
}
}
void swap_buffers(){
uint32_t* temp = disp_buffer;
disp_buffer = draw_buffer;
draw_buffer = temp;
sceKernelDcacheWritebackInvalidateall();
scedisplaySetFrameBuf(disp_buffer,512,PSP_disPLAY_PIXEL_FORMAT_8888,PSP_disPLAY_SETBUF_IMMEDIATE);
}
使用此代码,您将能够重现我的问题(您还需要初始化显示和控件,并设置退出回调以使程序工作,当然,还需要创建一个 Cell 类型的对象,称为 cl)。要在程序运行时注意问题,请在屏幕上移动方块并观察它。最终你会在屏幕上偶然发现一个区域,你的方块会在那里闪烁。离开该区域将停止闪烁,再次进入将再次开始闪烁。如果您使用时间检查调整 if() 并更改屏幕更新之间的时间,您会注意到闪烁区域将更改其在 Y 轴上的位置。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)