📄 browse.c
字号:
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
//
// Copyright (c) 2005 ZYM <yanming.zhang@gmail.com>
//
#include <pspctrl.h>
#include <stdio.h>
#include <string.h>
#include "main.h"
#include "chinesedraw.h"
unsigned long strbuftolong(unsigned char *s)
{
long l;
l = (*s) << 24;
l += (*(s+1)) << 16;
l += (*(s+2)) << 8;
l += (*(s+3));
return l;
}
int updateidxword(unsigned int idx, struct idxword *idxword)
{
unsigned char *p;
int len;
// idx must in range [0, wordcount-1]
if (idx>=wordcount)
idx = wordcount -1;
p= *(wordarray+idx);
len = strlen((char *)p)+1;
memcpy(idxword->word, p, ((len>MAXWORD)?MAXWORD:len));
idxword->index = idx;
idxword->dictoffset = strbuftolong(p+len);
idxword->dictlen = strbuftolong(p+len+4);
return idx;
}
int updatelist(unsigned int idx)
{
int i;
if (idx > (wordcount - WORDLIST_SIZE))
idx = wordcount - WORDLIST_SIZE;
memset((void *)&wordlist, 0, sizeof(struct idxword) * WORDLIST_SIZE);
for (i=0; i<WORDLIST_SIZE; i++) {
updateidxword(idx+i, &wordlist[i]);
}
return idx;
}
int updatecurrange(unsigned int first, unsigned int last)
{
unsigned int mid;
if ((first > last) || (last >wordcount)) {
// error
}
if ((last -first) <10)
return 0;
updateidxword(first, &currange.first);
updateidxword(last, &currange.last);
// maybe we should set it
// mid = first + (last -first) * 0.618
mid = (first + last)/2;
updateidxword(mid, &currange.mid);
return 1;
}
struct analogdirect {
// last delta move
unsigned int lastspeed;
// analog data [0..255]
unsigned char lastdata;
unsigned int count;
};
// analog pad get data about 30 counts in one second,
#define XPAGEDELTASIZE 90
unsigned int xpagedelta[XPAGEDELTASIZE]=
{
// first second
0, 0, 0, 1, 0, 0, 0, 0, 1, 0,
0, 0, 0, 1, 0, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 1, 1, 1, 1, 2,
// second second
2, 2, 2, 3, 3, 4, 4, 5, 6, 6,
7, 7, 8, 8, 9, 9, 10, 10, 11, 12,
13, 14, 14, 15, 15, 16, 16, 17, 17, 18,
// third second
18, 19, 19, 20, 21, 21, 22, 22, 23, 23,
24, 24, 25, 25, 26, 26, 27, 27, 28, 28,
29, 29, 30, 30, 31, 31, 32, 32, 33, 33,
};
#define YWORDDELTASIZE 30
unsigned int yworddelta[YWORDDELTASIZE]=
{
// first second
0, 0, 0, 1, 0, 0, 0, 0, 1, 0,
0, 0, 0, 1, 0, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 1, 1, 1, 1, 2,
};
struct analogdirect xleft, xright, yup, ydown;
void disp_browse_page(void);
void build_dictraw(struct idxword *idxp);
void ydict_browse(int laststate)
{
unsigned char x, y;
unsigned int button, lastinput;
struct ydictctrl yctrl;
if ((laststate == STATE_SELECTDICT)||(laststate==STATE_SWITCHMODE)) {
// init currange and wordlist
//updatecurrange(wordcount/3, wordcount / 3 * 2);
updatecurrange(0, wordcount -1);
updatelist(currange.mid.index);
// push word stack
memset((void *)&myidxstack, 0, sizeof(struct wordstack));
memcpy((void *)&myidxstack.stack[myidxstack.stacktop], (void *)&currange, sizeof(struct idxrange));
myidxstack.stacktop=1;
curword = 0;
curpage = 0;
}
lastinput =0;
while(1) {
if ((curword !=-1)&&(curpage == 0)) {
build_dictraw(&wordlist[curword]);
curwordrows= (strlen(*(wordarray+wordlist[curword].index))+C_LEN)/C_LEN;
dictpages = (curwordrows+dictrows+R_LEN)/R_LEN;
}
disp_browse_page();
getcontrol(&yctrl);
x = yctrl.x;
y = yctrl.y;
button = yctrl.buttons;
if (x<(MAXANALOG_X/2 - ANALOG_IGNORE)){
int delta;
// move previous pages
if (lastinput !=LASTINPUT_X_LEFT) {
xleft.count=1;
xleft.lastspeed=xpagedelta[xleft.count-1];
lastinput = LASTINPUT_X_LEFT;
}
else {
xleft.count++;
if (x<=xleft.lastdata) {
if (xleft.count<XPAGEDELTASIZE)
xleft.lastspeed=xpagedelta[xleft.count-1];
else {
xleft.lastspeed=xpagedelta[XPAGEDELTASIZE-1];
xleft.count--;
}
}
else {
if (xleft.count>30)
xleft.count -=30;
else
xleft.count=1;
xleft.lastspeed=xpagedelta[xleft.count-1];
}
}
xleft.lastdata=x;
delta =xleft.lastspeed * WORDLIST_SIZE;
if ((wordlist[0].index-delta) <WORDLIST_SIZE)
updatelist(0);
else
updatelist(wordlist[0].index -delta);
// update currange mid
updateidxword(wordlist[0].index, &currange.mid);
if (currange.first.index >= currange.mid.index)
updateidxword(currange.mid.index, &currange.first);
curword = 0;
curpage = 0;
}
else if (x>(MAXANALOG_X/2+ANALOG_IGNORE)){
int delta;
// move next pages
if (lastinput !=LASTINPUT_X_RIGHT) {
xright.count=1;
xright.lastspeed=xpagedelta[xright.count-1];
lastinput = LASTINPUT_X_RIGHT;
}
else {
xright.count++;
if (x>=xright.lastdata) {
if (xright.count<XPAGEDELTASIZE)
xright.lastspeed=xpagedelta[xright.count-1];
else {
xright.lastspeed=xpagedelta[XPAGEDELTASIZE-1];
xright.count--;
}
}
else {
if (xright.count>30)
xright.count -=30;
else
xright.count=1;
xright.lastspeed=xpagedelta[xright.count-1];
}
}
xright.lastdata=x;
delta =xright.lastspeed * WORDLIST_SIZE;
if ((wordlist[0].index + delta) > (wordcount - WORDLIST_SIZE))
updatelist(wordcount - WORDLIST_SIZE);
else
updatelist(wordlist[0].index + delta);
// update currange mid
updateidxword(wordlist[0].index, &currange.mid);
//update currange last
if (currange.last.index <= currange.mid.index)
updateidxword(currange.mid.index, &currange.last);
curword = 0;
curpage = 0;
}
else if (y<(MAXANALOG_Y/2 - ANALOG_IGNORE)){
int delta;
//move previous words
if (lastinput != LASTINPUT_Y_UP) {
yup.count=1;
yup.lastspeed =yworddelta[yup.count-1];
lastinput = LASTINPUT_Y_UP;
}
else {
yup.count++;
if (y>=yup.lastdata) {
if (yup.count<YWORDDELTASIZE)
yup.lastspeed=yworddelta[yup.count-1];
else {
yup.lastspeed=yworddelta[YWORDDELTASIZE-1];
yup.count--;
}
}
else {
yup.count=1;
yup.lastspeed=yworddelta[yup.count-1];
}
}
yup.lastdata=y;
delta = yup.lastspeed;
if (curword <delta) {
// jump to previous page
int i;
if (wordlist[curword].index >delta) {
i = wordlist[curword].index -delta;
updatelist(i);
updateidxword(i, &currange.mid);
}
else {
// jump to the first word in idx
updatelist(0);
// update currange mid
updateidxword(wordlist[0].index, &currange.mid);
}
//update currange first
if (currange.first.index >= currange.mid.index)
updateidxword(currange.mid.index, &currange.first);
curword = 0;
}
else {
curword -= delta;
}
curpage = 0;
}
else if (y>(MAXANALOG_Y/2+ANALOG_IGNORE)) {
//move next words
int delta;
if (lastinput !=LASTINPUT_Y_DOWN) {
ydown.count=1;
ydown.lastspeed =yworddelta[ydown.count-1];
lastinput = LASTINPUT_Y_DOWN;
}
else {
ydown.count++;
if (y>=ydown.lastdata) {
if (ydown.count<YWORDDELTASIZE)
ydown.lastspeed=yworddelta[ydown.count-1];
else {
ydown.lastspeed=yworddelta[YWORDDELTASIZE-1];
ydown.count--;
}
}
else {
ydown.count=1;
ydown.lastspeed=yworddelta[ydown.count-1];
}
}
ydown.lastdata=y;
delta = ydown.lastspeed;
if ((curword+delta)>(WORDLIST_SIZE-1)) {
// jump to next page
int i;
if ((wordlist[curword].index +delta) <(wordcount-1)) {
i=wordlist[curword].index +delta;
updatelist(i-WORDLIST_SIZE+1);
updateidxword(i, &currange.mid);
}
else {
updatelist(wordcount-WORDLIST_SIZE);
updateidxword(wordcount-1, &currange.mid);
}
if (currange.last.index<=currange.mid.index)
updateidxword(currange.mid.index, &currange.last);
curword = WORDLIST_SIZE -1;
}
else {
curword +=delta;
}
curpage = 0;
}
else if (!button){
lastinput= LASTINPUT_ANALOGNULL;
}
else {
lastinput=LASTINPUT_KEY;
switch(button)
{
case PSP_CTRL_SELECT:
//
gstate = STATE_SWITCHMODE;
return;
case PSP_CTRL_START:
// reset browse page
// clear myidxstack
memset((void *)&myidxstack, 0, sizeof(struct wordstack));
//updatecurrange(wordcount/3, wordcount / 3 * 2);
updatecurrange(0, wordcount -1);
updatelist(currange.mid.index);
// push word stack
memcpy((void *)&myidxstack.stack[myidxstack.stacktop], (void *)&currange, sizeof(struct idxrange));
myidxstack.stacktop++;
myidxstack.stacktop %= WORDSTACKSIZE;
curword = 0;
curpage = 0;
break;
case PSP_CTRL_UP:
// previous word
if (curword == 0){
int i;
if (wordlist[curword].index >0) {
i = wordlist[curword].index -1;
updatelist(i);
updateidxword(i, &currange.mid);
//update currange first
if (currange.first.index >= currange.mid.index)
updateidxword(currange.mid.index, &currange.first);
}
}
else {
curword +=(WORDLIST_SIZE -1);
curword %= WORDLIST_SIZE;
}
curpage = 0;
break;
case PSP_CTRL_DOWN:
// next word
if (curword == (WORDLIST_SIZE-1)) {
int i;
if (wordlist[curword].index <(wordcount-1)) {
i = wordlist[curword].index +1;
updatelist(i-WORDLIST_SIZE+1);
updateidxword(i, &currange.mid);
//update currange last
if (currange.last.index <= currange.mid.index)
updateidxword(currange.mid.index, &currange.last);
}
}
else {
curword++;
curword %= WORDLIST_SIZE;
}
curpage = 0;
break;
case PSP_CTRL_LEFT:
//previous list
{
if (wordlist[0].index <WORDLIST_SIZE)
updatelist(0);
else
updatelist(wordlist[0].index - WORDLIST_SIZE);
// update currange mid
updateidxword(wordlist[0].index, &currange.mid);
if (currange.first.index >= currange.mid.index)
updateidxword(currange.mid.index, &currange.first);
curword = 0;
}
curpage = 0;
break;
case PSP_CTRL_RIGHT:
//next list
{
if ((wordlist[0].index + WORDLIST_SIZE) > (wordcount - WORDLIST_SIZE))
updatelist(wordcount - WORDLIST_SIZE);
else
updatelist(wordlist[0].index + WORDLIST_SIZE);
// update currange mid
updateidxword(wordlist[0].index, &currange.mid);
//update currange last
if (currange.last.index <= currange.mid.index)
updateidxword(currange.mid.index, &currange.last);
curword = 0;
}
curpage = 0;
break;
case PSP_CTRL_SQUARE:
// first half of current range
{
int ret;
ret = updatecurrange(currange.first.index, currange.mid.index);
if (ret == 0)
break;
else {
updatelist(currange.mid.index);
// push word stack
memcpy((void *)&myidxstack.stack[myidxstack.stacktop], (void *)&currange, sizeof(struct idxrange));
myidxstack.stacktop++;
myidxstack.stacktop %= WORDSTACKSIZE;
curword = 0;
}
}
curpage = 0;
break;
case PSP_CTRL_CIRCLE:
// last half of current range
{
int ret;
ret = updatecurrange(currange.mid.index, currange.last.index);
if (ret ==0)
break;
else {
updatelist(currange.mid.index);
// push word stack
memcpy((void *)&myidxstack.stack[myidxstack.stacktop], (void *)&currange, sizeof(struct idxrange));
myidxstack.stacktop++;
myidxstack.stacktop %= WORDSTACKSIZE;
curword = 0;
}
}
curpage = 0;
break;
case PSP_CTRL_TRIANGLE:
// pop range stack, or previous page in dict mode
{
unsigned int i;
if (curpage>0) {
curpage--;
}
else {
//pop range stack
i = (myidxstack.stacktop + (WORDSTACKSIZE-2)) % WORDSTACKSIZE;
if (strlen(myidxstack.stack[i].first.word) ==0)
break;
else {
myidxstack.stacktop += (WORDSTACKSIZE -1);
myidxstack.stacktop %= WORDSTACKSIZE;
i = (myidxstack.stacktop + (WORDSTACKSIZE-1)) % WORDSTACKSIZE;
memset((void*)&myidxstack.stack[myidxstack.stacktop], 0, sizeof(struct idxrange));
memcpy((void *)&currange, (void *)&myidxstack.stack[i], sizeof(struct idxrange));
updatelist(currange.mid.index);
curword=0;
curpage=0;
}
}
}
break;
case PSP_CTRL_CROSS:
// view next page
// and mark this word
if ((curpage+1)<dictpages)
curpage++;
else {
if (tagfilep!=NULL) {
int idx;
unsigned char tag, c;
idx = wordlist[curword].index;
tag = *(tagfilep+idx);
c = ((tag&0x03) +1) %3;
*(tagfilep +idx) = (tag&0xF0) + c;
tagchanged = 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -