⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 browse.c

📁 PSP YDICT ver0.3 改进的功能 1。在《牛津现代英汉双解词典》中
💻 C
📖 第 1 页 / 共 2 页
字号:
//
//	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 + -