• R/O
  • SSH
  • HTTPS

owata:


File Info

Rev. 19
Size 36,045 bytes
Time 2008-02-26 20:03:37
Author bird_may_nike
Log Message

OSKの入力できる文字数を増やす

Content

/*
* $Id$
*/

#include "pspdialogs.h"
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <time.h>
#include <sys/unistd.h>
#include <arpa/inet.h>
#include <pspdebug.h>
#include <pspctrl.h>
#include <pspsdk.h>
#include <pspwlan.h>
#include "psp2ch.h"
#include "psp2chIta.h"
#include "psp2chThread.h"
#include "psp2chRes.h"
#include "psp2chFavorite.h"
#include "psp2chSearch.h"
#include "utf8.h"
#include "pg.h"
#include "cp932.h"
#include "intraFont.h"
#include "libCat/Cat_Network.h"
#include "libCat/Cat_Resolver.h"

extern int running; //main.c
extern char cwDir[256]; //main.c
extern void* framebuffer; // pg.c
extern unsigned long pgCursorX, pgCursorY; // pg.c
extern unsigned int list[512*512]; // pg.c
extern intraFont* jpn0; // pg.c

int tateFlag = 0;
int sel = 0;
const char* userAgent = "Monazilla/1.00 (Compatible; PSP; ja) owata\(^o^)/0.5.1";
const char* logDir = "log";
char cookie[128] = {0};
char keyWords[128];
SceCtrlData pad;
SceCtrlData oldPad;
MESSAGE_HELPER mh;
S_2CH_HEADER_COLOR resHeaderColor;
S_2CH_RES_COLOR resColor;
S_2CH_BAR_COLOR resBarColor;
S_2CH_HEADER_COLOR resAHeaderColor;
S_2CH_RES_COLOR resAColor;
S_2CH_BAR_COLOR resABarColor;
S_2CH_MENU_COLOR menuColor;
S_2CH_THREAD_COLOR threadColor;
S_2CH_ITA_COLOR cateOnColor;
S_2CH_ITA_COLOR cateOffColor;
S_2CH_FORM_COLOR formColor;
S_2CH_TXT_COLOR menuWinColor;

/*********************************
メインループ
runningが真の間ループ(×ボタンの終了やhomeボタンでの終了でrunningが0)
セレクター(sel)で各関数へ分岐
レス表示はお気に入り、板一覧、レス表示中リンクジャンプ、全板検索結果からラッパー関数へ移動
移動元に戻るためretSelを使用(レス表示からの"戻る"でsel = retSel実行)
全板検索も移動元に戻るためretSel使用
*********************************/
int psp2ch(void)
{
    int retSel = 0;

    sceCtrlSetSamplingCycle(0);
    sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG);
    while (running)
    {
        switch (sel)
        {
        case 1:
            psp2chFavorite();
            retSel = 1;
            break;
        case 2:
            psp2chIta();
            retSel = 2;
            break;
        case 3:
            psp2chThread(retSel);
            retSel = 3;
            break;
        case 4:
            retSel = psp2chFavoriteRes(retSel);
            break;
        case 5:
            retSel = psp2chThreadRes(retSel);
            break;
        case 6:
            retSel = psp2chJumpRes(retSel);
            break;
        case 7:
            psp2chSearch(retSel);
            retSel = 7;
            break;
        case 8:
            psp2chSearchRes(retSel);
            break;
        default:
            psp2chStart();
            break;
        }
    }
    return 0;
}

/*****************************
スタート画面
*****************************/
void psp2chStart(void)
{
    if(sceCtrlPeekBufferPositive(&pad, 1))
    {
        if (pad.Buttons != oldPad.Buttons)
        {
            oldPad = pad;
            if(pad.Buttons & PSP_CTRL_CROSS)
            {
                if (psp2chOwata())
                {
                    return;
                }
            }
            else if(pad.Buttons & PSP_CTRL_START)
            {
                sel = 2;
                return;
            }
            else if(pad.Buttons & PSP_CTRL_CIRCLE)
            {
                sel = 1;
                return;
            }
        }
        pgPrintMona();
        pgCopy(0, 0);
        sceDisplayWaitVblankStart();
        framebuffer = sceGuSwapBuffers();
    }
}

/*****************************
終了画面
*****************************/
int psp2chOwata(void)
{
    memset(&mh,0,sizeof(MESSAGE_HELPER));
    mh.options = PSP_UTILITY_MSGDIALOG_OPTION_TEXT | PSP_UTILITY_MSGDIALOG_OPTION_YESNO_BUTTONS;
    strcpy(mh.message, TEXT_3);
    pspShowMessageDialog(&mh, DIALOG_LANGUAGE_AUTO);
    sceCtrlPeekBufferPositive(&oldPad, 1);
    if (mh.buttonPressed == PSP_UTILITY_MSGDIALOG_RESULT_YES)
    {
        tateFlag = 0;
        pgPrintOwata();
        pgCopy(0, 0);
        framebuffer = sceGuSwapBuffers();
        pgWaitVn(10);
        running = 0;
        return 1;
    }
    return 0;
}

/*****************************
カーソル移動ルーチン
S_2CH_SCREEN構造体の
start:表示開始行
select:カーソル選択行
を変更しRボタン情報を返す
*****************************/
int psp2chCursorSet(S_2CH_SCREEN* line, int lineEnd)
{
    static int keyStart = 0, keyRepeat = 0;
    static clock_t keyTime = 0;
    int rMenu;
    int padUp = 0, padDown = 0;

    if (tateFlag)
    {
        if (pad.Lx == 255)
        {
            padUp = 1;
        }
        else if (pad.Lx == 0)
        {
            padDown = 1;
        }
    }
    else
    {
        if (pad.Ly == 0)
        {
            padUp = 1;
        }
        else if (pad.Ly == 255)
        {
            padDown = 1;
        }
    }

    if(pad.Buttons & PSP_CTRL_RTRIGGER)
    {
        rMenu = 1;
    }
    else
    {
        rMenu = 0;
    }
    if (pad.Buttons != oldPad.Buttons || keyRepeat || padUp || padDown)
    {
        if (pad.Buttons != oldPad.Buttons)
        {
            keyStart = 1;
        }
        else
        {
            keyStart = 0;
        }
        keyTime = clock();
        keyRepeat = 0;
        if((pad.Buttons & PSP_CTRL_UP && !tateFlag) || (pad.Buttons & PSP_CTRL_RIGHT && tateFlag) || padUp)
        {
            if (rMenu && !padUp)
            {
                line->start = 0;
                line->select = 0;
            }
            else
            {
                line->select--;
                if (line->select < 0)
                {
                    line->select = 0;
                }
                if (line->select < line->start)
                {
                    line->start = line->select;
                }
            }
        }
        if((pad.Buttons & PSP_CTRL_DOWN && !tateFlag) || (pad.Buttons & PSP_CTRL_LEFT && tateFlag) || padDown)
        {
            if (rMenu && !padDown)
            {
                line->start = line->count - lineEnd;
                if (line->start < 0)
                {
                    line->start = 0;
                }
                line->select = line->count - 1;
            }
            else
            {
                line->select++;
                if (line->select >= line->count)
                {
                    line->select = line->count -1;
                }
                if (line->select >= line->start + lineEnd)
                {
                    line->start = line->select - lineEnd + 1;
                }
                if (line->start < 0)
                {
                    line->start = 0;
                }
            }
        }
        if((pad.Buttons & PSP_CTRL_LEFT && !tateFlag) || (pad.Buttons & PSP_CTRL_UP && tateFlag))
        {
            if (line->select == line->start)
            {
                line->start -= lineEnd;
                if (line->start < 0)
                {
                    line->start = 0;
                }
            }
            line->select = line->start;
        }
        if((pad.Buttons & PSP_CTRL_RIGHT && !tateFlag) || (pad.Buttons & PSP_CTRL_DOWN && tateFlag))
        {
            if (line->select == line->start + lineEnd - 1)
            {
                line->start += lineEnd;
                if (line->start + lineEnd >= line->count)
                {
                    line->start = line->count - lineEnd;
                }
                if (line->start < 0)
                {
                    line->start = 0;
                }
            }
            line->select = line->start + lineEnd - 1;
            if (line->select >= line->count)
            {
                line->select = line->count -1;
            }
        }
    }
    else
    {
        if (keyStart)
        {
            if (clock() - keyTime > 400000)
            {
                keyRepeat = 1;
            }
        }
        else
        {
            if (clock() - keyTime > 5000)
            {
                keyRepeat = 1;
            }
        }
    }
    return rMenu;
}

/*****************************
アナログパッドで横スクロール
xReverseを-1にするとスクロール方向が反転する
設定ファイル実装時に設定項目とする予定
*****************************/
int psp2chPadSet(int scrollX)
{
    static int xReverse = 1;

    if (tateFlag)
    {
        if (pad.Ly == 0)
        {
            scrollX += 8 * xReverse;
        }
        else if (pad.Ly == 255)
        {
            scrollX -= 8 * xReverse;
        }
        if (scrollX > BUF_HEIGHT - SCR_HEIGHT)
        {
            scrollX = BUF_HEIGHT - SCR_HEIGHT;
        }
    }
    else
    {
        if (pad.Lx == 0)
        {
            scrollX += 4 * xReverse;
        }
        else if (pad.Lx == 255)
        {
            scrollX -= 4 * xReverse;
        }
        if (scrollX > BUF_WIDTH - SCR_WIDTH)
        {
            scrollX = BUF_WIDTH - SCR_WIDTH;
        }
    }
    if (scrollX < 0)
    {
        scrollX = 0;
    }
    return scrollX;
}

/***********************************
外部カラーセット
color.iniを読み込んで各カラーをセット
************************************/
#define setColor(A, B, C) \
    p = strstr(buf, (A));\
    if (p) {\
        p = strstr(p, "0x");\
        if(p){\
            p+=2;\
            sscanf(p, "%X", &(B));\
        }\
        else{(B) = (C);}\
    }\
    else{(B) = (C);}
void psp2chSetColor(void)
{
    SceUID fd;
    SceIoStat st;
    char file[256];
    char *buf;
    char *p;
    int ret;

    sprintf(file, "%s/color.ini", cwDir);
    ret = sceIoGetstat(file, &st);
    if (ret >= 0)
    {
        buf = (char*)malloc(st.st_size + 1);
        if (buf)
        {
            fd = sceIoOpen(file, PSP_O_RDONLY, 0777);
            if (fd >= 0)
            {
                sceIoRead(fd, buf, st.st_size);
                sceIoClose(fd);
                buf[st.st_size] = '\0';
                setColor("RES_NUMBER", resHeaderColor.num, RED);
                setColor("RES_NAME_HEAD", resHeaderColor.name1, BLACK);
                setColor("RES_NAME_BODY", resHeaderColor.name2, RGB(0x00, 0xCC, 0x00));
                setColor("RES_MAIL", resHeaderColor.mail, RGB(0x99, 0x99, 0x99));
                setColor("RES_DATE", resHeaderColor.date, BLACK);
                setColor("RES_ID_HEAD_1", resHeaderColor.id1, BLUE);
                setColor("RES_ID_HEAD_2", resHeaderColor.id2, RED);
                setColor("RES_ID_BODY", resHeaderColor.id3, BLUE);
                setColor("RES_TEXT", resColor.text, BLACK);
                setColor("RES_BG", resColor.bg, RGB(0xE0, 0xE0, 0xE0));
                setColor("RES_LINK", resColor.link, BLUE);
                setColor("RES_BAR_SLIDER", resBarColor.slider, YELLOW);
                setColor("RES_BAR_BG", resBarColor.bg, RGB(0x66, 0x66, 0xFF));

                setColor("RES_A_NUMBER", resAHeaderColor.num, RED);
                setColor("RES_A_NAME_HEAD", resAHeaderColor.name1, BLACK);
                setColor("RES_A_NAME_BODY", resAHeaderColor.name2, RGB(0x00, 0xCC, 0x00));
                setColor("RES_A_MAIL", resAHeaderColor.mail, RGB(0x99, 0x99, 0x99));
                setColor("RES_A_DATE", resAHeaderColor.date, BLACK);
                setColor("RES_A_ID_HEAD_1", resAHeaderColor.id1, BLUE);
                setColor("RES_A_ID_HEAD_2", resAHeaderColor.id2, RED);
                setColor("RES_A_ID_BODY", resAHeaderColor.id3, BLUE);
                setColor("RES_A_TEXT", resAColor.text, BLACK);
                setColor("RES_A_BG", resAColor.bg, RGB(0xFF, 0xFF, 0xCC));
                setColor("RES_A_LINK", resAColor.link, BLUE);
                setColor("RES_A_BAR_SLIDER", resABarColor.slider, RGB(0x00, 0xFF, 0xCC));
                setColor("RES_A_BAR_BG", resABarColor.bg, RGB(0xCC, 0xFF, 0xFF));

                setColor("MENU_TEXT", menuColor.text, WHITE);
                setColor("MENU_BG", menuColor.bg, BLACK);
                setColor("MENU_BATTERY_1", menuColor.bat1, GREEN);
                setColor("MENU_BATTERY_2", menuColor.bat2, YELLOW);
                setColor("MENU_BATTERY_3", menuColor.bat3, RED);

                setColor("THREAD_NUMBER", threadColor.num, RED);
                setColor("THREAD_CATEGORY", threadColor.category, RED);
                setColor("THREAD_TEXT_1", threadColor.text1, BLUE);
                setColor("THREAD_TEXT_2", threadColor.text2, RED);
                setColor("THREAD_BG", threadColor.bg, RGB(0xCC, 0xFF, 0xCC));
                setColor("THREAD_COUNT_1", threadColor.count1, BLACK);
                setColor("THREAD_COUNT_2", threadColor.count2, BLACK);
                setColor("THREAD_SELECT_NUMBER", threadColor.s_num, RED);
                setColor("THREAD_SELECT_CATEGORY", threadColor.s_category, RGB(0x99, 0x00, 0x00));
                setColor("THREAD_SELECT_TEXT_1", threadColor.s_text1, RGB(0x00, 0x00, 0x99));
                setColor("THREAD_SELECT_TEXT_2", threadColor.s_text2, RGB(0x99, 0x00, 0x00));
                setColor("THREAD_SELECT_BG", threadColor.s_bg, GRAY);
                setColor("THREAD_SELECT_COUNT_1", threadColor.s_count1, BLACK);
                setColor("THREAD_SELECT_COUNT_2", threadColor.s_count2, BLACK);

                setColor("CATE_ON_TEXT", cateOnColor.cate.text, RGB(0xCC, 0x33, 0x00));
                setColor("CATE_ON_BG", cateOnColor.cate.bg, WHITE);
                setColor("CATE_ON_S_TEXT", cateOnColor.cate.s_text, WHITE);
                setColor("CATE_ON_S_BG", cateOnColor.cate.s_bg, RGB(0xCC, 0x33, 0x00));
                setColor("ITA_OFF_TEXT", cateOnColor.ita.text, RGB(0x66, 0x66, 0xFF));
                setColor("ITA_OFF_BG", cateOnColor.ita.bg, GRAY);
                setColor("ITA_OFF_S_TEXT", cateOnColor.ita.s_text, GRAY);
                setColor("ITA_OFF_S_BG", cateOnColor.ita.s_bg, RGB(0x66, 0x66, 0xFF));
                setColor("CATE_ON_BASE", cateOnColor.base, WHITE);

                setColor("CATE_OFF_TEXT", cateOffColor.cate.text, RGB(0x88, 0x99, 0x66));
                setColor("CATE_OFF_BG", cateOffColor.cate.bg, GRAY);
                setColor("CATE_OFF_S_TEXT", cateOffColor.cate.s_text, GRAY);
                setColor("CATE_OFF_S_BG", cateOffColor.cate.s_bg, RGB(0x88, 0x99, 0x66));
                setColor("ITA_ON_TEXT", cateOffColor.ita.text, BLUE);
                setColor("ITA_ON_BG", cateOffColor.ita.bg, WHITE);
                setColor("ITA_ON_S_TEXT", cateOffColor.ita.s_text, WHITE);
                setColor("ITA_ON_S_BG", cateOffColor.ita.s_bg, BLUE);
                setColor("CATE_OFF_BASE", cateOffColor.base, WHITE);

                setColor("FORM_TITLE_TEXT", formColor.title, WHITE);
                setColor("FORM_TITLE_BG", formColor.title_bg, RED);

                setColor("MENU_WIN_TEXT", menuWinColor.text, GRAY);
                setColor("MENU_WIN_BG", menuWinColor.bg, BLACK);
                setColor("MENU_WIN_S_TEXT", menuWinColor.s_text, WHITE);
                setColor("MENU_WIN_S_BG", menuWinColor.s_bg, BLUE);
                free(buf);
                return;
            }
            else
            {
                free(buf);
            }
        }
    }
    // iniファイルがない時のデフォルト
    // レス本文
    resHeaderColor.num = RED;
    resHeaderColor.name1 = BLACK;
    resHeaderColor.name2 = RGB(0x00, 0xCC, 0x00);
    resHeaderColor.mail = RGB(0x99, 0x99, 0x99);
    resHeaderColor.date = BLACK;
    resHeaderColor.id1 = BLUE;
    resHeaderColor.id2 = RED;
    resHeaderColor.id3 = BLUE;
    resColor.text = BLACK;
    resColor.bg = RGB(0xE0, 0xE0, 0xE0);
    resColor.link = BLUE;
    resBarColor.slider = YELLOW;
    resBarColor.bg = RGB(0x66, 0x66, 0xFF);
    // レスアンカー 
    resAHeaderColor.num = RED;
    resAHeaderColor.name1 = BLACK;
    resAHeaderColor.name2 = RGB(0x00, 0xCC, 0x00);
    resAHeaderColor.mail = RGB(0x99, 0x99, 0x99);
    resAHeaderColor.date = BLACK;
    resAHeaderColor.id1 = BLUE;
    resAHeaderColor.id2 = RED;
    resAHeaderColor.id3 = BLUE;
    resAColor.text = BLACK;
    resAColor.bg = RGB(0xFF, 0xFF, 0xCC);
    resAColor.link = BLUE;
    resABarColor.slider = RGB(0x00, 0xFF, 0xCC);
    resABarColor.bg = RGB(0xCC, 0xFF, 0xFF);
    // メニューバー 
    menuColor.text = WHITE;
    menuColor.bg = BLACK;
    menuColor.bat1 = GREEN;
    menuColor.bat2 = YELLOW;
    menuColor.bat3 = RED;
    // スレッド一覧
    threadColor.num = RED;
    threadColor.category = RED;
    threadColor.text1 = BLUE;
    threadColor.text2 = RED;
    threadColor.bg = RGB(0xCC, 0xFF,0xCC);
    threadColor.count1 = BLACK;
    threadColor.count2 = BLACK;
    threadColor.s_num = RED;
    threadColor.s_category = RGB(0x99, 0x00, 0x00);
    threadColor.s_text1 = RGB(0x00, 0x00, 0x99);
    threadColor.s_text2 = RGB(0x99, 0x00, 0x00);
    threadColor.s_bg = GRAY;
    threadColor.s_count1 = BLACK;
    threadColor.s_count2 = BLACK;
    // カテゴリー・板一覧
    cateOnColor.cate.text = RGB(0xCC, 0x33, 0x00);
    cateOnColor.cate.bg = WHITE;
    cateOnColor.cate.s_text = WHITE;
    cateOnColor.cate.s_bg = RGB(0xCC, 0x33, 0x00);
    cateOnColor.ita.text = RGB(0x66, 0x66, 0xFF);
    cateOnColor.ita.bg = GRAY;
    cateOnColor.ita.s_text = GRAY;
    cateOnColor.ita.s_bg = RGB(0x66, 0x66, 0xFF);
    cateOnColor.base = WHITE;
    cateOffColor.cate.text = RGB(0x88, 0x99, 0x66);
    cateOffColor.cate.bg = GRAY;
    cateOffColor.cate.s_text = GRAY;
    cateOffColor.cate.s_bg = RGB(0x88, 0x99, 0x66);
    cateOffColor.ita.text = BLUE;
    cateOffColor.ita.bg = WHITE;
    cateOffColor.ita.s_text = WHITE;
    cateOffColor.ita.s_bg = BLUE;
    cateOffColor.base = WHITE;
    // 送信フォーム
    formColor.title = WHITE;
    formColor.title_bg = RED;
    // メニューウィンドウ
    menuWinColor.text = GRAY;
    menuWinColor.bg = BLACK;
    menuWinColor.s_text = WHITE;
    menuWinColor.s_bg = BLUE;
}

/***********************************
ネットモジュールのロード初期化
************************************/
int psp2chInit(void)
{
    int ret;

    ret = sceUtilityLoadNetModule(PSP_NET_MODULE_COMMON);
    if (ret < 0)
    {
        memset(&mh,0,sizeof(MESSAGE_HELPER));
        strcpy(mh.message, "Load module common errror");
        pspShowMessageDialog(&mh, DIALOG_LANGUAGE_AUTO);
        return ret;
    }
    ret = sceUtilityLoadNetModule(PSP_NET_MODULE_INET);
    if (ret < 0)
    {
        memset(&mh,0,sizeof(MESSAGE_HELPER));
        strcpy(mh.message, "Load module inet errror");
        pspShowMessageDialog(&mh, DIALOG_LANGUAGE_AUTO);
        return ret;
    }
    ret = Cat_NetworkInit();
    if (ret < 0)
    {
        memset(&mh,0,sizeof(MESSAGE_HELPER));
        strcpy(mh.message, "Cat_NetworkInit errror");
        pspShowMessageDialog(&mh, DIALOG_LANGUAGE_AUTO);
        return ret;
    }
    psp2chSetColor();
    return 0;
}

/**************************
終了前の後始末
**************************/
int psp2chTerm(void)
{
    Cat_NetworkTerm();
    return 0;
}

/*****************************
アクセスポイントへ接続してソケット作成
成功時にはソケット(>=0)を返す
失敗時には<0を返す
psp2chRequest()とpsp2chPost()から呼ばれます。
*****************************/
int psp2chOpenSocket(void)
{
    int mySocket, ret;

    ret = psp2chApConnect();
    if (ret < 0 && ret != 0x80110405)
    {
        return ret;
    }
    mySocket = socket(PF_INET, SOCK_STREAM, 0 );
#ifdef DEBUG
    pspDebugScreenPrintf("socket = %d\n", mySocket);
#endif
    return mySocket;
}

/*****************************
ソケットを閉じる
*****************************/
int psp2chCloseSocket(int mySocket)
{
    shutdown(mySocket, SHUT_RDWR);
    return close(mySocket);
}

/*****************************
名前解決 ホスト名をIPアドレスに変換
Sfiya猫さんのパッチ使用
*****************************/
int psp2chResolve(const char* host, struct in_addr* addr)
{
    SceUID fd;
    char buf[256];
    char hosts[2048];
    char *p;

    sprintf(buf, "  %s のアドレスを解決しています", host);
    pgMenuBar(buf);
    sceDisplayWaitVblankStart();
    framebuffer = sceGuSwapBuffers();
    sprintf(buf, "%s/hosts", cwDir);
    fd = sceIoOpen(buf, PSP_O_RDONLY, 0777);
    if (fd >= 0)
    {
        sceIoRead(fd, hosts, sizeof(hosts));
        sceIoClose(fd);
        p = strstr(hosts, host);
        if (p)
        {
            *p = '\0';
            p = strrchr(hosts, '\n');
            if (p)
            {
                sscanf(p, " %s", buf);
                if (inet_aton(buf, addr))
                {
                    return 0;
                }
            }
        }
    }
    if(Cat_ResolverURL( host, addr ) < 0 )
    {
        pgMenuBar("  Cat_ResolverURL error");
        sceDisplayWaitVblankStart();
        framebuffer = sceGuSwapBuffers();
        return -1;
    }
    return 0;
}

/*****************************
HTTP で GETリクエスト
ソケットを作成
アドレス解決してリクエストヘッダを送信します
成功時にはソケット(>=0)を返します
*****************************/
int psp2chRequest(const char* host, const char* path, const char* header) {
    int mySocket;
    int ret;
    char requestText[512];
    char buf[512];
    struct sockaddr_in sain;
    struct in_addr addr;
    char *p;

    mySocket = psp2chOpenSocket();
    if (mySocket < 0) {
        return mySocket;
    }
    p = strrchr(path, '#');
    if (p)
    {
        *p = '\0';
    }
    sprintf(requestText,
        "GET /%s HTTP/1.1\r\n"
        "Host: %s\r\n"
        "User-Agent: %s\r\n"
        "%s"
        "Connection: close\r\n\r\n"
        , path, host, userAgent, header);
    ret = psp2chResolve(host, &addr);
    if (ret < 0) {
        return ret;
    }
    sprintf(buf, "  %s (%s)", host, inet_ntoa(addr));
    pgMenuBar(buf);
    sceDisplayWaitVblankStart();
    framebuffer = sceGuSwapBuffers();
    // Tell the socket to connect to the IP address we found, on port 80 (HTTP)
    sain.sin_family = AF_INET;
    sain.sin_port = htons(80);
    sain.sin_addr.s_addr = addr.s_addr;
    sprintf(buf, "  http://%s/%s に接続しています", host, path);
    pgMenuBar(buf);
    sceDisplayWaitVblankStart();
    framebuffer = sceGuSwapBuffers();
    ret = connect(mySocket,(struct sockaddr *)&sain, sizeof(sain) );
    if (ret < 0) {
        memset(&mh,0,sizeof(MESSAGE_HELPER));
        strcpy(mh.message, "Connect errror");
        pspShowMessageDialog(&mh, DIALOG_LANGUAGE_AUTO);
        sceCtrlPeekBufferPositive(&oldPad, 1);
        return ret;
    }
    pgMenuBar("接続しました");
    sceDisplayWaitVblankStart();
    framebuffer = sceGuSwapBuffers();
#ifdef DEBUG
    pspDebugScreenPrintf("send request\n%s\n", requestText);
#endif
    // send our request
    send(mySocket, requestText, strlen(requestText), 0 );

    return mySocket;
}

/*****************************
HTTP で POST 送信します。
ソケット作成
アドレス解決してヘッダとボディを送信
成功時にはソケット(>=0)を返す
*****************************/
int psp2chPost(char* host, char* dir, int dat, char* cook, char* body)
{
    int mySocket;
    int ret;
    char requestText[512];
    char buf[512];
    struct sockaddr_in sain;
    struct in_addr addr;

    mySocket = psp2chOpenSocket();
    if (mySocket < 0) {
        return -1;
    }
    sprintf(requestText,
        "POST /test/bbs.cgi HTTP/1.1\r\n"
        "Host: %s\r\n"
        "User-Agent: %s\r\n"
        "Referer: http://%s/test/read.cgi/%s/%d/l50\r\n"
        "Cookie: %s\r\n"
        "Content-Type: application/x-www-form-urlencoded\r\n"
        "Content-Length: %d\r\n\r\n"
        , host, userAgent, host, dir, dat, cook, strlen(body));
    ret = psp2chResolve(host, &addr);
    if (ret < 0) {
        return -1;
    }
    sprintf(buf, "  %s (%s)", host, inet_ntoa(addr));
    pgMenuBar(buf);
    sceDisplayWaitVblankStart();
    framebuffer = sceGuSwapBuffers();
    // Tell the socket to connect to the IP address we found, on port 80 (HTTP)
    sain.sin_family = AF_INET;
    sain.sin_port = htons(80);
    sain.sin_addr.s_addr = addr.s_addr;
    sprintf(buf, "  http://%s/test/bbs.cgi に接続しています", host);
    pgCopy(0, 0);
    pgMenuBar(buf);
    sceDisplayWaitVblankStart();
    framebuffer = sceGuSwapBuffers();
    ret = connect( mySocket,(struct sockaddr *)&sain, sizeof(sain) );
    if (ret < 0) {
        memset(&mh,0,sizeof(MESSAGE_HELPER));
        sprintf(mh.message, "Can't connect bbs.cgi");
        pspShowMessageDialog(&mh, DIALOG_LANGUAGE_AUTO);
        return -1;
    }
#ifdef DEBUG
    pspDebugScreenPrintf("send request\n%s\n", requestText);
#endif
    // send our request
    send(mySocket, requestText, strlen(requestText), 0 );
    send(mySocket, body, strlen(body), 0 );
    return mySocket;
}

/*****************************
ソケットから最初の1行(ステータスライン)を読み込みます。
ステータスコードをintに変換して返す
HTTP/1.1 200 OK
なら200を返す
*****************************/
int psp2chGetStatusLine(int mySocket)
{
    char in;
    char incomingBuffer[256];
    int i = 0;
    int verMajor, verMinor, code;
    char phrase[256];

     do
     {
        if (recv( mySocket, &in, 1, 0 ) == 0)
        {
            return -1;
        }
        incomingBuffer[i] = in;
        if (++i > 255)
        {
            return -1;
        }
    } while (in != '\n');
    incomingBuffer[i] = '\0';
    pgMenuBar(incomingBuffer);
    sceDisplayWaitVblankStart();
    framebuffer = sceGuSwapBuffers();
    sscanf(incomingBuffer, "HTTP/%d.%d %d %s\r\n", &verMajor, &verMinor, &code, phrase);
    return code;
}

/*****************************
ソケットからレスポンスヘッダを読み込みます。
HTTP_HEADERS構造体に
Content-Length
Content-Type
Last-Modified
ETag
の内容がコピーされます。
cookie[]にSet-Cookieの内容が追加されます。
Content-Lengthがintで返されます
Content-Lengthを返さない場合もあるので注意(CGI等)
*****************************/
int psp2chGetHttpHeaders(int mySocket, HTTP_HEADERS* header)
{
    int i = 0;
    char in;
    char incomingBuffer[256];
    int contentLength = 0;
    char *p;

    while(recv(mySocket, &in, 1, 0) > 0)  // if recv returns 0, the socket has been closed.
    {
        if (in == '\r')
        {
            continue;
        }
        incomingBuffer[i] = in;
        i++;
        if (in == '\n')
        {
            incomingBuffer[i] = 0;
            if (incomingBuffer[0] == '\n')  // End of headers
            {
                break;
            }
            if (strstr(incomingBuffer, "Content-Length:"))
            {
                sscanf(incomingBuffer, "Content-Length: %d\n", &contentLength);
                header->Content_Length = contentLength;
            }
            else if (strstr(incomingBuffer, "Content-Type:"))
            {
                strcpy(header->Content_Type, &incomingBuffer[14]);
            }
            else if (strstr(incomingBuffer, "Last-Modified:"))
            {
                strcpy(header->Last_Modified, &incomingBuffer[15]);
            }
            else if (strstr(incomingBuffer, "ETag:"))
            {
                strcpy(header->ETag, &incomingBuffer[6]);
            }
            else if (strstr(incomingBuffer, "Set-Cookie:"))
            {
                p = strchr(incomingBuffer, ';');
                *p = '\0';
                if (cookie[0])
                {
                    strcat(cookie, "; ");
                }
                strcat(cookie, &incomingBuffer[12]);
            }
#ifdef DEBUG
            pspDebugScreenPrintf("%s", incomingBuffer);
#endif
            i = 0;
        }
    }
    return contentLength;
}

static void draw_callback( void* pvUserData )
{
    // 描画処理
    // ダイアログ表示のさいの背景を描画する

    minimalRender();
}

static void screen_update_callback( void* pvUserData ) {
    // 更新処理
    // フレームバッファのスワップなど

    sceGuSync( 0, 0 );
    sceDisplayWaitVblankStartCB();
    framebuffer = sceGuSwapBuffers();
}

/*****************************
指定された設定番号のアクセスポイントに接続します
psp2chApConnect()から呼ばれます。
*****************************/
int connect_to_apctl(int config)
{
    int err;
    int stateLast = -1;
    int state;
    char buf[32];
    clock_t time;

    err = sceNetApctlConnect(config);
    if (err != 0)
    {
        memset(&mh,0,sizeof(MESSAGE_HELPER));
        strcpy(mh.message, "sceNetApctlConnect error");
        pspShowMessageDialog(&mh, DIALOG_LANGUAGE_AUTO);
        return 0;
    }

    pgMenuBar("  Connecting...");
    sceDisplayWaitVblankStart();
    framebuffer = sceGuSwapBuffers();
    time = clock();
    while (1)
    {
        err = sceNetApctlGetState(&state);
        if (err != 0)
        {
            memset(&mh,0,sizeof(MESSAGE_HELPER));
            sprintf(mh.message, "sceNetApctlGetState error\n0x%X", err);
            pspShowMessageDialog(&mh, DIALOG_LANGUAGE_AUTO);
            break;
        }
        if (state == 2)
        {
            strcpy(buf, " アクセスポイントに接続中です。");
            stateLast = state;
        }
        if (state == 3)
        {
            strcpy(buf, " IPアドレスを取得中です。");
            stateLast = state;
        }
        if (state == 4)
        {
            break;  // connected with static IP
        }
        pgMenuBar(buf);
        sceDisplayWaitVblankStart();
        framebuffer = sceGuSwapBuffers();
        if (clock() > time + 1000000 * 8)
        {
            break;
        }
    }
    if (state != 4)
    {
        pgMenuBar("  接続に失敗しました。");
    }
    else
    {
        pgMenuBar("  接続しました。");
        Cat_ResolverInitEngine();
    }
    sceDisplayWaitVblankStart();
    framebuffer = sceGuSwapBuffers();
    return 0;
}

/*****************************
PSP内のアクセスポイント設定を検索します
設定が2個以上あれば選択ダイアログを表示します。
設定が1個のみの場合はその値で接続します。
設定がない場合は-1が返されます。
*****************************/
int psp2chApConnect(void)
{
    struct
    {
        int index;
        char name[128];
    } ap[2];
    int count = 0;
    int i;
    char buf[32];

    memset(&mh,0,sizeof(MESSAGE_HELPER));
    mh.options = PSP_UTILITY_MSGDIALOG_OPTION_TEXT;
    if (sceWlanGetSwitchState() == 0)
    {
        strcpy(mh.message, TEXT_1);
        pspShowMessageDialog(&mh, DIALOG_LANGUAGE_AUTO);
        return -1;
    }
    else if (sceWlanDevIsPowerOn() == 0)
    {
        strcpy(mh.message, TEXT_2);
        pspShowMessageDialog(&mh, DIALOG_LANGUAGE_AUTO);
        return -1;
    }
    if (sceNetApctlGetInfo(8, buf) == 0)
    {
        // IP取得済み
        return 0;
    }
    pgMenuBar("接続の設定を検索しています...");
    pgWaitVn(2);
    framebuffer = sceGuSwapBuffers();
    for (i = 1; i < 100; i++) // skip the 0th connection
    {
        if (sceUtilityCheckNetParam(i) != 0) continue;  // more
        sceUtilityGetNetParam(i, 0, (netData*) ap[count].name);
        ap[count].index = i;
        count++;
        if (count > 1) break;  // no more room
    }
    if (count == 1)
    {
        return connect_to_apctl(ap[0].index);
    }
    else if (count > 1)
    {
        // 返り値 < 0 : エラー
        // 返り値 = 0 : 接続した
        // 返り値 > 0 : キャンセルされた
        return Cat_NetworkConnect( draw_callback, screen_update_callback, 0 );
        // 全部0なのかな???
    }
    return -1;
}

/*****************************
OnScreenKeyboardで文字入力
title: OSKの右下に表示されるタイトル文字列(SJIS)
text:入力文字を保存するポインタ
num:入力文字列の長さ
lines:入力文字列の行数
OSKからはワイド文字(UCS)で帰ってくるのでSJISに変換しています。
*****************************/
void psp2chGets(char* title, char* text, int num, int lines)
{
    unsigned short* wc;
    unsigned char* p;
    char* s;
    int sjis, i;
    unsigned short string[128];
    unsigned short pretext[2048];
    OSK_HELPER helper;
    char* buf = "人生オワタ\(^o^)/";

    if (num > 2048)
    {
        num = 2048;
    }
    /* sjis => ucs */
    if (title && *title != '\0')
    {
        p = (unsigned char*)title;
    }
    else
    {
        p = (unsigned char*)buf;
    }
    i = 0;
    while (*p && i < 127)
    {
        sjis = conv_sjiswin_wchar(*p++);
        if (sjis == -1)
        {
            continue;
        }
        string[i] = (unsigned short)sjis;
        i++;
    }
    string[i] = 0;
    i = 0;
    p = (unsigned char*)text;
    while (*p && i < 2048)
    {
        sjis = conv_sjiswin_wchar(*p++);
        if (sjis == -1)
        {
            continue;
        }
        pretext[i] = (unsigned short)sjis;
        i++;
    }
    pretext[i] = 0;
    memset(&helper,0,sizeof(OSK_HELPER));
    helper.title = (unsigned short*)string;
    helper.pretext = (unsigned short*)pretext;
    helper.textlength = num;
    helper.textlimit = num;
    helper.lines = lines;

    pspShowOSK(&helper,DIALOG_LANGUAGE_AUTO);
    /* ucs => sjis */
    wc = (unsigned short*)helper.text;
    s = text;
    i = 0;
    while (*wc)
    {
        sjis = conv_wchar_sjiswin((int)(*wc++));
        if (sjis < 0x100)
        {
            s[i] = sjis;
            i++;
        }
        else
        {
            if (i >= num - 2)
            {
                break;
            }
            s[i] = sjis & 0xFF;
            i++;
            s[i] = (sjis>>8) & 0xFF;
            i++;
        }
        if (i >= num - 1)
        {
            break;
        }
    }
    s[i] = '\0';
}

/****************
入力ダイアログ表示
text1: ダイアログに表示されるタイトル
text2: OSKに表示するタイトル
戻り値 0=入力, -1=取消し
*****************/
int psp2chInputDialog(const unsigned short* text1, char* text2)
{
    int temp;

    temp = tateFlag;
    tateFlag = 0;
    keyWords[0] = '\0';
    while (running)
    {
        if(sceCtrlPeekBufferPositive(&pad, 1))
        {
            if (pad.Buttons != oldPad.Buttons)
            {
                oldPad = pad;
                if(pad.Buttons & PSP_CTRL_CIRCLE)
                {
                    psp2chGets(text2, keyWords, 128, 1);
                }
                if(pad.Buttons & PSP_CTRL_CROSS)
                {
                    tateFlag = temp;
                    return -1;
                }
                if(pad.Buttons & PSP_CTRL_SQUARE)
                {
                    break;
                }
            }
            sceGuStart(GU_DIRECT, list);
            sceGuClearDepth(0);
            sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT);
            pgFillvram(BLUE, 80, 60, 320, 45);
            pgEditBox(WHITE, 140, 85, 340, 100);
            pgCursorX = 142;
            pgCursorY =  87;
            pgPrint(keyWords, BLACK, WHITE, 340);
            pgCopy(0, 0);
            pgMenuBar(" ○ : 入力   × : 戻る   □ : 決定");
            pgCursorX = 240;
            pgCursorY =  77;
            intraFontSetStyle(jpn0, 1.0f, YELLOW, 0, INTRAFONT_ALIGN_CENTER);
            intraFontPrintUCS2(jpn0, pgCursorX, pgCursorY, text1);
            sceGuFinish();
            sceGuSync(0,0);
        }
        sceDisplayWaitVblankStart();
        framebuffer = sceGuSwapBuffers();
    }
    tateFlag = temp;
    return 0;
}
Show on old repository browser