include ivram.inc ASCII1_SP_CHECK equ 2800h ASCII1_SP_START equ 2E00h JAPAN2_SP_START equ 0E00h IGNORE_SPRITE equ 0FFFFh bseg s_info dw ? ; スプライト情報(iv_sprite) s_max dw ? ; スプライトmax s_overlay dw ? ; 重ねあわせmax s_vvram dw ? ; 仮想VRAM s_vvramend dw ? ; 終端 + 1 s_count dw ? ; 登録スプライト数 c_info dw IV_CHARTABLE_MAX dup (?) ; キャラクタ情報(iv_charinfo) c_charmax dw IV_CHARTABLE_MAX dup (?) ; テーブル単位の最大キャラ数 c_tables dd IV_CHARTABLE_MAX dup (?) ; キャラクタバッファ endbseg cseg ;------------------------------------------------------ ; void ivs_set_chartable ; (int tableno, int max, BYTE* info_buf, BYTE far* char_buf); ;------------------------------------------------------ public _ivs_set_chartable needeven _ivs_set_chartable proc near center mov bx, [bp + CPARAM1] ; bx: tableno shl bx, 1 ; bx: tableno * 2 mov ax, [bp + CPARAM2] mov c_charmax[bx], ax mov ax, [bp + CPARAM3] mov c_info[bx], ax shl bx, 1 ; bx: tableno * 4 mov ax, [bp + CPARAM4] mov c_tables[bx].farofs, ax mov ax, [bp + CPARAM5] mov c_tables[bx].farseg, ax ssct_ret: cleave ret _ivs_set_chartable endp ;------------------------------------------------------ ; void ivs_sprite_init ; (BYTE* sprite_buf, int max, BYTE* vvram_buf, int overlay_max); ;------------------------------------------------------ public _ivs_sprite_init needeven _ivs_sprite_init proc near center mov ax, [bp + CPARAM1] mov s_info, ax mov ax, [bp + CPARAM2] mov s_max, ax mov ax, [bp + CPARAM3] mov s_vvram, ax mov ax, [bp + CPARAM4] cmp ax, IV_OVERLAY_MIN jae short ssi_10 mov ax, IV_OVERLAY_MIN ssi_10: mov s_overlay, ax shl ax, 1 mov bx, IV_CXY mul bx add ax, s_vvram mov s_vvramend, ax ssi_ret: cleave ret _ivs_sprite_init endp ;------------------------------------------------------ ; void ivs_start_render(WORD flags); ;------------------------------------------------------ public _ivs_start_render needeven _ivs_start_render proc near center mov s_count, 0 ssr_vclear: mov bx, [bp + CPARAM1] ; bx: flags test bx, IV_STARTRENDER_NOVRAMINIT jnz short ssr_novclear mov bx, s_vvram mov cx, IV_CXY mov ax, IGNORE_SPRITE mov dx, s_overlay shl dx, 1 ssr_cl10: mov [bx], ax add bx, dx loop ssr_cl10 ssr_novclear: ssr_ret: cleave ret _ivs_start_render endp ;------------------------------------------------------ ; void ivs_end_render(void); ;------------------------------------------------------ public _ivs_end_render needeven _ivs_end_render proc near center sub sp, IV_CHAR_UNITSIZE mov bp, sp ; bp: render buffer push si push di push es mov si, s_vvram ; si: vvram pointer xor di, di ; di: vram pointer ser_10: mov cx, s_overlay ser_20: mov ax, [si] ; ax: sprite number cmp ax, s_count jae short ser_blt cmp ax, IGNORE_SPRITE je short ser_blt ser_render: push cx push si push di push ss ; es:di: render buffer pop es mov di, bp mov bx, ax shl bx, 2 ; bx: iv_sprite pointer add bx, s_info mov ax, [bx].ivs_param ; ax: param call [bx].ivs_renderer pop di pop si pop cx add si, 2 loop ser_20 ser_blt: add si, cx ; si: next vvram add si, cx cmp cx, s_overlay jne short ser_blt10 ser_noblt: add di, IV_CHAR_UNITSIZE jmp short ser_blt20 ser_blt10: push si push ds xor ax, ax mov ds, ax mov ax, IV_VRAMSEG mov es, ax mov si, bp rept IV_CHAR_UNITSIZE / 2 movsw endm pop ds pop si ser_blt20: cmp si, s_vvramend jb short ser_10 ser_ret: add bp, IV_CHAR_UNITSIZE pop es pop di pop si cleave ret _ivs_end_render endp ;------------------------------------------------------ ; void ivs_add_sprite(int charno, int x, int y); ;------------------------------------------------------ public _ivs_add_sprite needeven _ivs_add_sprite proc near center push si push di sas_check: mov ax, s_count cmp ax, s_max jae short sas_ret sas_xy: mov bl, [bp + CPARAM2] mov bh, [bp + CPARAM3] mov di, bx ; di: y, x sas_charinfo: mov si, [bp + CPARAM1] ; si: charno mov ax, si call get_charinfo test al, IV_CHARINFO_NORENDER jnz short sas_ret test al, IV_CHARINFO_OPAQUE jz short sas_normal sas_opaque: mov bx, di call get_vvram_address jc short sas_ret mov [bx], IGNORE_SPRITE mov ax, si mov bx, di mov dx, offset cs:render_opaque call ivsa_add_renderer sas_normal: mov ax, si mov bx, di mov dx, offset cs:render_normal call ivsa_add_renderer sas_ret: pop di pop si cleave ret _ivs_add_sprite endp ;------------------------------------------------------ ; void ivs_add_sprite_rect ; (int charno, int x, int y, int w, int h, int delta); ;------------------------------------------------------ public _ivs_add_sprite_rect needeven _ivs_add_sprite_rect proc near center push si ; -2 push di ; -4 sasr_mkstack: mov si, [bp + CPARAM1] ; si: charno mov ax, [bp + CPARAM2] ; w += x add [bp + CPARAM4], ax push [bp + CPARAM3] ; -6 y sub sp, 4 ; -8 x ; -10 charno sasr_10: mov di, [bp + CPARAM2] ; di: x sasr_20: mov [bp - 10], si mov [bp - 8], di call _ivs_add_sprite inc si inc di cmp di, [bp + CPARAM4] jl short sasr_20 add si, [bp + CPARAM6] inc word ptr [bp - 6] dec word ptr [bp + CPARAM5] jnz short sasr_10 add sp, 6 pop di pop si cleave ret _ivs_add_sprite_rect endp ;------------------------------------------------------ ; void ivs_add_opaque_rect(int charno, int x, int y, int w, int h); ;------------------------------------------------------ public _ivs_add_opaque_rect needeven _ivs_add_opaque_rect proc near center push si push di saor_check: mov ax, [bp + CPARAM4] ; (w == 0) || (h == 0) or ax, [bp + CPARAM5] jz short saor_ret saor_counter: mov ax, [bp + CPARAM4] ; ax: w * h mul word ptr [bp + CPARAM5] mov di, s_max sub di, s_count ; di: all count jbe short saor_ret cmp ax, di ja short saor_10 mov di, ax saor_10: mov si, [bp + CPARAM1] ; si: charno mov bh, [bp + CPARAM3] ; bh: y saor_20: mov bl, [bp + CPARAM2] ; bl: x mov cx, [bp + CPARAM4] ; cx: w saor_30: push bx call get_vvram_address jc short saor_35 mov [bx], IGNORE_SPRITE saor_35: pop bx push bx push cx push di mov ax, si mov dx, offset cs:render_opaque call ivsa_add_renderer pop di pop cx pop bx inc bl dec di jz saor_ret loop saor_30 inc bh jmp short saor_20 saor_ret: pop di pop si cleave ret _ivs_add_opaque_rect endp ;------------------------------------------------------ ; ivsa_add_renderer -- renderer 追加 ;in ; bl, bh: x, y (no clip) ; dx: renderer ; ax: render param ;break ; bx, cx, di ;------------------------------------------------------ public ivsa_add_renderer needeven ivsa_add_renderer proc near push ax ; > push dx ; >> call get_vvram_address ; bx: vvram jnc short ar_ok add sp, 4 ret ar_ok: mov di, bx ; di: vvram mov cx, s_overlay ar_find: cmp [bx], IGNORE_SPRITE je short ar_add add bx, 2 loop ar_find ar_shift: mov bx, di add bx, 2 ; bx: vvram[1] mov cx, s_overlay sub cx, 2 ; cx: s_overlay - 2 ar_shift10: mov ax, [bx + 2] mov [bx], ax add bx, 2 loop ar_shift10 ar_add: pop dx ; << pop ax ; < mov di, bx ; di: add point mov bx, s_count mov [di], bx shl bx, 2 ; bx: iv_sprite pointer add bx, s_info mov [bx].ivs_renderer, dx mov [bx].ivs_param, ax jcxz ar_add10 mov [di + 2], IGNORE_SPRITE ar_add10: inc s_count ar_ret: ret ivsa_add_renderer endp ;------------------------------------------------------ ; render_xxx -- renderer ; ;in ; ax: param ; es:di: render buffer ; ; rendererはbp,ds,ssを変更してはならない。 ;------------------------------------------------------ ;------------------------------------------------------ ; render_opaque -- 塗りつぶしキャラクタ ; ;in ; ax: param(charno) ;------------------------------------------------------ needeven render_opaque proc near call get_chardata ; dx:si: chardata push ds mov ds, dx rept IV_CHAR_UNITSIZE / 2 add si, 2 movsw endm pop ds ret render_opaque endp ;------------------------------------------------------ ; render_normal -- 通常のスプライト ; ;in ; ax: param(charno) ;------------------------------------------------------ needeven render_normal proc near call get_chardata ; dx:si: chardata push ds mov ds, dx rept IV_CHAR_UNITSIZE / 2 lodsw and ax, es:[di] mov bx, ax lodsw or ax, bx stosw endm pop ds ret render_normal endp ;------------------------------------------------------ ; render_fill_line -- ラインパターン塗りつぶし ; ;in ; ax: param(pattern) ;------------------------------------------------------ needeven render_fill_line proc near rept IV_CHAR_UNITSIZE / 2 stosw endm ret render_fill_line endp ;------------------------------------------------------ ; get_vram_address -- VRAMアドレス算出 ; ;in ; bl, bh: x, y ;out ; bx(ax): address ;------------------------------------------------------ needeven get_vram_address proc near mov al, IV_CX ; ax: y*IV_CX mul bh xor bh, bh add ax, bx ; ax: +x shl ax, 4 ; ax: *IV_CHAR_UNITSIZE mov bx, ax ret get_vram_address endp ;------------------------------------------------------ ; get_vvram_address -- 仮想VRAMアドレス算出 ; ;in ; bl, bh: x, y ;out ; cf: clipped ; bx(ax): address ;break ; dx ;------------------------------------------------------ needeven get_vvram_address proc near gvva_check: test bl, bl js short gvva_clip test bh, bh js short gvva_clip cmp bl, IV_CX jae short gvva_clip cmp bh, IV_CY jb short gvva_noclip gvva_clip: stc ret gvva_noclip: mov al, IV_CX ; ax: y*IV_CX mul bh xor bh, bh add ax, bx ; ax: +x mov bx, s_overlay shl bx, 1 mul bx add ax, s_vvram ; no need 'clc' mov bx, ax ret get_vvram_address endp ;------------------------------------------------------ ; get_chardata -- キャラデータ ; ;in ; ax: charno ;out ; dx:si: pointer ;break ; ax, bx, cx ;------------------------------------------------------ needeven get_chardata proc near call get_ctable_index shl bx, 1 mov si, cx shl si, 5 ; si: *IV_CHAR_UNITSIZE*2 add si, c_tables[bx].farofs mov dx, c_tables[bx].farseg ret get_chardata endp ;------------------------------------------------------ ; get_charinfo -- charinfo取得 ; ;in ; ax: charno ;out ; al: charinfo ;break ; bx, cx, dx ;------------------------------------------------------ needeven get_charinfo proc near call get_ctable_index mov bx, c_info[bx] add bx, cx mov al, [bx] ret get_charinfo endp ;------------------------------------------------------ ; get_ctable_index -- charno からテーブルインデックス算出 ; ;in ; ax: charno ;out ; bx: テーブルインデックス*2 ; cx: テーブル中でのインデックス ;break ; dx ;------------------------------------------------------ needeven get_ctable_index proc near mov cx, ax xor bx, bx gci_loop: mov dx, c_charmax[bx] cmp cx, dx jb short gci_found sub cx, dx add bx, 2 jmp short gci_loop gci_found: ret get_ctable_index endp ;------------------------------------------------------ ; void iv_adjust_sp() -- SP補正によるIRAM確保 ; 注意:現在は使用していない。 ;------------------------------------------------------ public _iv_adjust_sp needeven _iv_adjust_sp proc near ; ASCII1かどうかをSPでチェック mov ax, sp cmp ax, ASCII1_SP_CHECK ja short aasp_ok aasp_ng: panic IV_PANIC_INVALIDSP aasp_ok: push si push di push es mov ax, ss mov es, ax mov cx, ASCII1_SP_START sub cx, sp mov di, JAPAN2_SP_START sub di, cx mov bx, di mov si, ASCII1_SP_START sub si, cx shr cx, 1 rep movs word ptr es:[di], es:[si] mov sp, bx pop es pop di pop si sub bp, ASCII1_SP_START - JAPAN2_SP_START aasp_ret: ret _iv_adjust_sp endp endcseg end